Javascript中的作用域链

Javascript中的作用域链,javascript,scope-chain,Javascript,Scope Chain,我读过Javascript中的scope chain,但对我来说没有任何意义,有人能告诉我什么是scope chain,它是如何与图形或连傻瓜都能理解的东西一起工作的吗。我在谷歌上搜索了一下,但没有发现什么可以理解的:(这是关于闭包的。您可以在内部范围中使用外部范围的变量: function get_inner_scope () { var outer = 'Outer variable value'; return function () { alert(out

我读过Javascript中的scope chain,但对我来说没有任何意义,有人能告诉我什么是scope chain,它是如何与图形或连傻瓜都能理解的东西一起工作的吗。我在谷歌上搜索了一下,但没有发现什么可以理解的:(

这是关于闭包的。您可以在内部范围中使用外部范围的变量:

function get_inner_scope () {
    var outer = 'Outer variable value';
    return function () {
        alert(outer);
    }
}
f = get_inner_scope();
f(); // alerts Outer variable value
first google的链接提供了更多关于其他样本的详细信息:

ECMAScript(JS基于的核心语言)中的任何函数调用都会生成一个单独的执行上下文,该上下文彼此独立运行。在每个执行上下文中,
引用所讨论的对象,默认为函数附加到的任何对象

function foo() {
    alert(this===window)
}
将警告true,因为窗口是拥有“foo”方法的对象。函数中定义的任何变量都可以通过该函数的唯一作用域链环境访问

function world() {
    var name = 'global';
    alert(name)
}
显然会提醒“全球”

function world() {
    var name = 'global';
    (function() {
        var name = 'country';
        alert(name)
    })();
    alert(name)
}
在最新的示例中,当调用第一个警报时,Javascript确定在内部函数的作用域链中定义了标识符
name
,因此它不必查找作用域链来获取它

在第二次警报调用中,
name
也在同一上下文中定义,并发出“全局”警报

function world() {
    var name = 'global';
    (function() { alert(name) })();
}
在本例中,
名称
标识符未在同一上下文中定义,因此它必须沿作用域链向上移动到定义名称的外部函数,并向全局发出警报

参考:


要理解范围链,您必须知道闭包是如何工作的

嵌套函数时会形成闭包,内部函数可以引用其外部封闭函数中的变量,即使其父函数已经执行

JavaScript通过遍历作用域链,从本地移动到全局,在特定上下文中解析标识符

考虑以下具有三个嵌套函数的示例:

var currentScope = 0; // global scope
(function () {
  var currentScope = 1, one = 'scope1';
  alert(currentScope);
  (function () {
    var currentScope = 2, two = 'scope2';
    alert(currentScope);
    (function () {
      var currentScope = 3, three = 'scope3';
      alert(currentScope);
      alert(one + two + three); // climb up the scope chain to get one and two
    }());
  }());
}());
建议案文如下:


我知道这是一篇老文章,但它仍然对开发人员很有帮助。我想用一种稍微不同的方式来做,因为它会让初学者更容易理解范围链接。下面是我修改过的代码版本:

var currentScope = 0; // global scope
function a () {
   var currentScope = 1, one = 'scope1';
   alert(currentScope);

  function b () {
      var currentScope = 2, two = 'scope2';
      alert(currentScope);

      function c () {
         var currentScope = 3, three = 'scope3';
         alert(currentScope);
  alert(one + two + three); // climb up the scope chain to get one and two
     }
     c();
  }
  b();
}
a();

亚历克斯是一个快乐的人,在一个晴朗的日子,手里拿着月薪走在路上被抢劫

后来他意识到明天是支付女儿1000美元学费的最后一天。
他跑回家,发现自己有400美元的积蓄,担心剩下的(600美元)。闪现的第一个念头是向父亲马修借一些。
贫穷的木匠马修身无分文,以300美元的价格卖掉了他继承的手镯,并借给了他的儿子亚历克斯。
亚历克斯在社会上享有良好声誉,他立即从当地一家银行拿到剩余的300美元,并按时支付女儿的学费

返回Javascript中的作用域链:
Alex-javascript中的函数
Mathew立即数函数,Alex嵌套在其中。
Mathew嵌套在直接函数Mathew中。
银行全局变量。

function Bank() {
    loan=300;
    Mathew();

    function Mathew() {
        mathew=300;
        Alex();

        function Alex() {
            savings:400;
            alert('I need some money');
        }

    }

}

Bank();
此时Alex的范围链如下所示: [储蓄:400]+[mathew:300]+[loan:300];

摘要: 作用域链用于解析javascript中变量名的值。没有作用域链,如果在不同的作用域中定义了多个变量,javascript引擎将不知道为某个变量名选择哪个值。javascript中的作用域链是词汇定义的,这意味着我们可以看到作用域是什么在中,将通过查看代码

作用域链的顶部是全局作用域,它是浏览器中的
窗口
对象(
NodeJS
中的
global
)。除了全局作用域之外,函数还有自己的变量作用域。可以通过查看函数定义的位置来确定作用域链

解析变量时,内部函数首先查看自己的作用域。如果在自己的作用域中找不到该变量,它将沿着作用域链向上爬,并在定义函数的环境中查找变量名。如下所示:

因此,在我们的图像示例中,当
innerFoo
使用变量
bar
时,它首先尝试在innerFoo(函数体中的代码)的范围内查找它。然后当它在这里找不到它时,会沿着作用域链向上爬到
foo
。在
foo
中,也没有名为
bar
的变量。因此,它会沿着作用域链向上爬,现在查看全局作用域。全局作用域中有一个名为bar的变量,其值为10,
bar
将得到解决

例子:
设foo=1;
设bar=1;
功能测试(bar){
返回函数innerTestFunc(){
设foo=10;
console.log(foo,bar);
}
}
const innerTestFunc1=测试(5);
const innerTestFunc2=测试(20);
innerTestFunc1();//日志10,5

innerTestFunc2();//日志10、20
因此,currentScope 3将覆盖currentScope 1的值?@Aaron不是覆盖,而是阴影。@Aaron,正如@kangax所说的,在第三个函数的范围内,在第二个、第一个和全局范围上声明的
currentScope
变量将被简单地阴影或隐藏,它们的值将在o上保持不变uter闭包,因为在第三个函数中,您正在声明一个新的
currentScope
变量,该变量驻留在该范围中,并且当您访问它时,它将是范围链中的第一个变量。但是如果我想在第二个函数中访问范围链,那么它将是3,因为变量定义的位置而不是位置变量被执行了?我想我得到了,这与我以前的想法不同。让我告诉你我所理解的:每个变量实际上从它被执行的地方得到值