1. 变量和常量
1.1 概念
我们先分清两个概念:
变量:存储数值的容器
常量:只读的常量(一旦申明,不能改变)
变量不是数值本身,它们仅仅是一个用于存储数值的容器。
1.2 定义
1.2.1 规则:
- 由字母数字下划线和$组成
- 不能以数字开头
- 严格区分大小写
- 不能使用关键字和保留字
合法变量:
username
_age
_23
$23
不合法变量名:
class
4n
var
if
ES6保留字(Reserved keywords as of ECMAScript 2015)
| break | export | super | case | extends | switch |
| this | class | for | throw | const | function |
| if | typeof | debugger | import | var | default |
| in | void | delete | instanceof | while | do |
| new | with | else | return | yield |
保留字(Future reserved keywords)
| enum | await |
严格模式下保留字
| implements | package | public | interface | private | static | let | protected |
前标准(ES1-ES3)保留字
| abstract | float | synchronized | boolean | goto | throws |
| transient | char | long | volatile | double | native |
| final | short | null | true | false |
1.2.2 var
// 定义变量
var title = 'hello world';
// 定义多个变量
var username = 'Moddest', age = 29, sex = 'man';
1.2.3 let(ES6)
let title = 'hello world';
// 定义多个变量
let username = 'Moddest', age = 29, sex = 'man';
1.2.4 const(ES6):常量
const title = 'hello world';
// 定义多个常量
const username = 'Moddest', age = 29, sex = 'man';
1.3 注意
- const注意事项
const申明常量,一旦申明,无法改变。
但是。。。
const user = { name: 'Moddest' };
user.age = 20;
console.log(user.age); // 正确:20
user = { height: 175 }; // 错误:TypeError: "user" is read-only
究其本质:
const定义的常量值,如果是
简单的数据类型(数值,布尔值,字符串):值保存在对应的内存地址,不能改变
复合类型的数据(对象和数组):变量指向内存地址,保存的是实际数据的指针,内部值的改变不受影响
- var,let,const区别
1. 区别1:“变量提升”
var:存在变量提升
let:不存在变量提升
const:不存在变量提升
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
2. 区别2: “暂时性死区(temporal dead zone,简称 TDZ)”
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
typeof也不是百分百安全的操作哦(之前可以先typeof检测,再用var定义变量)
目的:ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为
- 不允许重复申明
let a = 12;
let a = 34; // 报错
-
为什么要用块级作用域
第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date();
function f() {
console.log(tmp); // undefined
if (false) {
// 因为此处存在变量提升
var tmp = 'hello world';
}
}
f(); // undefined
第二种场景,用来计数的循环变量泄露为全局变量。
var s = 'hello';
// 改用let则避免i成为全局变量
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5