# 作用域
函数的每次调用都有与之紧密相关的作用域和上下文。从根本上来说,作用域是基于函数的,而上下文是基于对象的。
上下文始终是 this
关键字的值,它是拥有(控制)当前所执行代码的对象的引用。
注意:对回调函数而言,在浏览器中,回调函数中的this为window或undefined(严格模式),而在Node.js中, 回调函数的this为global。
# 例子
是由于在函数rain内局部变量x在整个函数体内都有定义( var x= 'rain-man',进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出'undefined'是因为,第一个执行alert(x)时,局部变量x仍未被初始化。
var x = 1;
function rain(){
alert( x ); //弹出 'undefined',而不是1
var x = 'rain-man';
alert( x ); //弹出 'rain-man'
}
rain();
# 闭包
闭包的特点:
- 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
- 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
# 块级作用域
let
与 const
声明变量仅在代码块内有用。
{
const c = 3;
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
c // ReferenceError: c is not defined.
// var 变量提升,i 为全局引用
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
// let i 仅在本轮循环有效
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
- 作用域,let 与 自执行函数
for(var i = 0; i < 2 ; i++) {
setTimeout(() => {
console.log(i)
}, 200)
}
setTimeout(() => {
console.log('--------------')
}, 300)
for(var i = 0; i < 2 ; i++) {
var c = i
setTimeout(() => {
console.log(c)
}, 400)
}
setTimeout(() => {
console.log('--------------')
}, 500)
for(var i = 0; i < 2 ; i++) {
let c = i
setTimeout(() => {
console.log(c)
}, 600)
}
setTimeout(() => {
console.log('--------------')
}, 700)
for(var i = 0; i < 2 ; i++) {
(() => {
var c = i
setTimeout(function() {
console.log(c)
}, 800)
})()
}
# 参考资料
← setTimeout 函数 →