一、变量
在应用程序中,使用变量来作为值的符号名。变量的名字又叫做标识符,其需要遵守一定的规则。一个 JavaScript 标识符必须以字母、下划线(_)或者美元符号($)开头;后续的字符也可以是数字(0-9)。因为 JavaScript 语言是区分大小写的,这里所指的字母可以是“A”到“Z”(大写的)和“a”到“z”(小写的)
var声明变量
变量声明,无论发生在何处,都在执行任何代码之前进行处理。用var声明的变量的作用域是它当前的执行上下文,它可以是嵌套的函数,也可以是声明在任何函数外的变量。
1.声明和未声明变量之间的差异是:
(1)声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的
function x() {
y = 1; // 在严格模式(strict mode)下会抛出ReferenceError异常。
var z = 2;
}
x();
console.log(y); // 打印"1" 。
console.log(z); // 抛出ReferenceError: z未在x外部声明。
(2)声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作的时候才会被创建
console.log(a); // 抛出ReferenceError。
console.log('still going...'); // 永不执行。
var a;
console.log(a); // 打印"undefined"或""(不同浏览器实现不同)。
console.log('still going...'); // 打印"still going..."。
(3)声明变量是它所在上下文环境的不可配置属性,非声明变量是可配置的(如非声明变量可以被删除)
var a = 1;
b = 2;
delete this.a; // 在严格模式(strict mode)下抛出TypeError,其他情况下执行失败并无任何提示。
delete this.b;
console.log(a, b); // 抛出ReferenceError。
// 'b'属性已经被删除。
因此,建议始终声明变量,无论它们是在函数还是全局作用域内。 而在 ECMAScript 5 严格模式下,分配给未声明的变量会引发错误
2.变量提升
由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明
var a = 10;
//可以理解为
var a;
a = 10;
因此,建议始终在作用域顶部声明变量(全局代码的顶部和函数代码的顶部),这可以清楚知道哪些变量是函数作用域(本地),哪些变量在作用域链上解决。重要的是,提升将影响变量声明,而不会影响其值的初始化
let声明变量
let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是,它声明的变量只能是全局或者整个函数块的。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数
1.let作用域与var作用域对比
当在块中使用时,let
将变量的作用域限制为该块。注意
var
的作用域在它被声明的函数内的区别
function varTest() {
var x = 1;
if (true) {
var x = 2; // 同样的变量!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}
2.暂存死区
在 ECMAScript 2015 中,let绑定不受变量提升的约束,这意味着let声明不会被提升到当前执行上下文的顶部。在块中的变量初始化之前,引用它将会导致 ReferenceError(而使用 var 声明变量则恰恰相反,该变量的值是 undefined )。该变量处于从块开始到初始化处理的“暂存死区”。
function do_something() {
console.log(bar); // undefined
console.log(foo); // ReferenceError: foo is not defined
var bar = 1;
let foo = 2;
}
二、常量
你可以用关键字 const 创建一个只读的常量。常量标识符的命名规则和变量相同:必须以字母、下划线或美元符号开头并可以包含有字母、数字或下划线。
- 常量不可以通过赋值改变其值,也不可以在脚本运行时重新声明。它必须被初始化为某个值
- 常量的作用域规则与 let 块级作用域变量相同。若省略const关键字,则该标识符将被视为变量
- 在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量