作用域

函数的每次调用都有与之紧密相关的作用域和上下文。从根本上来说,作用域是基于函数的,而上下文是基于对象的。

上下文始终是 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();

闭包

闭包的特点:

  1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
  2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

块级作用域

letconst 声明变量仅在代码块内有用。

{
  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)
  })()
}

参考资料

Last Updated: 3/20/2020, 9:09:07 AM