作用域和闭包

JavaScript 词法作用域和动态作用域

作用域是指程序源代码中定义变量的区域。

作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

采用的是词法作用域,也就是静态作用域。

静态作用域(词法作用域)

JavaScript 采用的是词法作用域,所以函数的作用域在函数定义的时候就决定了

而与词法作用域相对的动态的作用域,函数的作用域在函数调用的时候才决定的。

让我们认真看个例子就能明白之间的区别:

var value = 1;
function foo() {
  console.log(value);
}
function bar() {
  var value = 2;
  foo();
}
bar();
//????
复制代码

这里使用的是 js 语言所以使用的是静态作用域(词法作用域),让我们分析下执行的过程:

执行 foo 函数,首先在它的内部作用域查找是否有 value 这个局部变量,如果有就会使用这个局部变量;
没有,根据书写的代码就会向上一层寻找,这是我们发现 value 变量存在是 1;

来自小犀牛题目(题 2 我翻车了)

var scope = "global scope";
function checkscope() {
  var scope = "local scope";
  function f() {
    return scope;
  }
  return f();
}
checkscope();
// ????

var scope = "global scope";
function checkscope() {
  var scope = "local scope";
  function f() {
    return scope;
  }
  return f;
}
checkscope()();
复制代码

我觉的 return f 就是将 f 的方法暴露在最外层,执行 checkscope 等于执行 f;间接的以为 checkscope === f ,实际则是 f 方法 存在与 checkscope 的作用域内,执行时返回了 f 方法作用域并没有相互覆盖或者抵消

如果你也翻车了那么你也默默的

JavaScript 采用的是词法作用域,所以函数的作用域在函数定义的时候就决定了;

JavaScript 采用的是词法作用域,所以函数的作用域在函数定义的时候就决定了;

JavaScript 采用的是词法作用域,所以函数的作用域在函数定义的时候就决定了;

引用《JavaScript 权威指南》的回答就是

JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效

动态作用域(JS 没有采用这种编译模式)

采用动态作用域的语言有 Emacs Lisp、Common Lisp(兼有静态作用域)、Perl(兼有静态作用域)。C/C++的宏中用到的名字,也是动态作用域。

采用动态作用域的变量叫做动态变量。

略略略(1000 字)

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享