Javascript 中的作用域链

IT技术 javascript scope-chain
2021-02-06 09:00:13

我已经在 J​​avascript 中阅读了作用域链,但它对我没有任何意义,谁能告诉我什么是作用域链以及它如何与图形一起工作或什至白痴都能理解的东西。我用谷歌搜索,但我没有找到可以理解的东西:(

6个回答

要理解作用域链,你必须知道闭包是如何工作的。

当您嵌套函数时会形成一个闭包,即使在其父函数已经执行之后,内部函数也可以引用其外部封闭函数中存在的变量。

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

推荐阅读:

但是,如果我想在第二个函数中访问 scopeChain 那么它会是 3 吗,因为定义变量的地方而不是执行变量的地方?
2021-03-25 09:00:13
@Aaron 不是覆盖,而是shadow
2021-03-27 09:00:13
@Aaron,正是因为@kangax说,该范围内的第三个功能currentScope变量的声明第二,第一和全球范围将被简单地遮蔽隐藏,其value将保持在外部封闭完好,因为在第三个功能,您正在声明一个驻留在该范围内 currentScope变量,因此当您在那里访问它时,它将成为范围链中的第一个变量。
2021-03-28 09:00:13
那么,currentScope 3 会覆盖 currentScope 1 的值吗?
2021-04-08 09:00:13
我想我明白了,这与我之前的想法不同。让我告诉你我的理解:每个变量实际上从定义而不是执行的地方获取值,因此函数有自己的范围,例如 currentScope 3 隐藏了currentScope 2 的值,因为它们定义在不同的范围内,但是如果我想在第二个函数中访问 c​​urrentScope 它将返回 2 因为 currentScope 3 仅在第三个函数中有效,它只影响在其自身范围内定义的变量。现在说得通了。所以如果我不使用var,那么我碰巧定义了一个全局变量
2021-04-10 09:00:13

ECMAScript(JS 所基于的核心语言)中的任何函数调用都会产生一个单独的执行上下文,它们彼此独立运行。在每个执行上下文中,this指的是有问题的对象,默认为函数所附加的任何对象。

function foo() {
    alert(this===window)
}

警报为真,因为窗口是拥有 '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) })();
}

在这个例子中,name标识符不是在同一个上下文中定义的,因此它必须沿着作用域链向上移动到定义名称的外部函数,并且它会向全局发出警报。

参考:

我知道这是一个旧帖子,但它仍然对开发人员有帮助。我想用一点不同的方式来做,因为它对初学者理解作用域链会更友好。这是我修改后的代码版本:

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();
关于-1,我想知道我的版本是否对“白痴”理解没有帮助(如原始问题所述)。
2021-03-17 09:00:13
我不认为你的评论是无用的。虽然它实际上与第一个示例相同,但我同意第一个示例中的许多立即调用函数表达式可能会让 Javascript 初学者感到尴尬。但是,我会在函数的开头而不是最后调用函数,因为它会使代码更具可读性,恕我直言。
2021-03-27 09:00:13

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

function get_inner_scope () {
    var outer = 'Outer variable value';
    return function () {
        alert(outer);
    }
}
f = get_inner_scope();
f(); // alerts Outer variable value

通过第一个谷歌链接获得其他示例的更多详细信息:http : //blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx

用外行术语解释 Javascript 中的作用域链

亚历克斯是个快乐的人,一天晴朗,拿着月薪走在路上被抢劫了。

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

回到 Javascript 中的作用域链:
Alex-javascript
Mathew 中的一个函数Mathew-立即函数,Alex 嵌套在其中。
Mathews 的父母-立即函数 Mathew 嵌套在
Bank-Global 变量中。

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

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

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

    }

}

Bank();

Alex 的作用域链此时看起来像:[savings:400]+[mathew:300]+[loan:300];