一、变量的声明
1、var特点
(1)只存在函数作用域和全局作用域
(2)存在变量提升,对于未声明的变量typeof操作是安全的,返回undefined。
function getValue(condition) {
if (condition) {
var value = 'like';
return value;
}
}
在预编译阶段,上述代码被修改为:
function getValue(condition) {
var value;
if (condition) {
var value = 'like';
return value;
}
//此处也可访问value,其值为undefined
}
2、let特点
(1)块级作用域、函数作用域、全局作用域
(2)变量不会提升,存在临时死区,同一作用域内禁止重声明
3、const特点
(1)同let
(2)常量如果是对象,不允许修改绑定,但允许修改属性值
const person = {
name: 'mike'
}
// ok
person.name = 'lily';
// 抛出错误
person = {}
4、备注
1、循环
(1)对于var声明,循环里的每次迭代同事共享着变量i,循环内部创建的函数全部保留了对相同变量的引用。
var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func() // 输出10次数字10
})
(2)对于let/const声明,每次迭代循环都会创建一个新变量,并以之前迭代中的同名变量的值将其初始化。
var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(function(func) {
func() // 输出0 1 2 3 4 5 6 7 8 9
})
2、全局作用域
(1)对于var,全局定义的属性即是window对象的属性,因此可能无意中覆盖一个已经存在的全局属性。
window.ncz = 'hello';
var ncz = 'hi';
console.log(window.ncz) // "hi"
(2)对于let/const,全局定义的属性不会添加为全局对象的属性,其不会覆盖全局变量,只能遮蔽它。
window.ncz='hello';
let ncz = 'hi';
console.log(window.ncz) // "hello"