【问题标题】:Why is this not a closure that allows an inner function to access an outer function variable?为什么这不是一个允许内部函数访问外部函数变量的闭包?
【发布时间】:2014-03-17 17:36:11
【问题描述】:

如何通过闭包访问 funcB 中的变量“e”?

<!DOCTYPE HTML>
<html>
<head>
<script>
Test = function () {};
Test.prototype.funcA = function (k)  {
    var that = this;
    return  function(e) {
        window.console.log('k: ' + k); // 'abc'
        window.console.log('e: ' + e); // 'def'
        that.funcB(k);
    };
};
Test.prototype.funcB = function (p) {
    window.console.log('p: ' + p); // 'abc'
    window.console.log('e: ' + e); // undefined (why?)
}
obj = new Test();
(obj.funcA('abc'))('def');
</script>
</head>
<body>
</body>
</html>

我对关闭感到困惑。

既然funcA中存在变量e(打印'def'),为什么funcB是由funcA执行的,所以funcB不能访问它?如何让 funcB 访问变量 e?

我希望变量 e 可以通过闭包访问。我不想将它存储在实例化对象上(我知道我可以这样做)。

【问题讨论】:

    标签: javascript closures prototype


    【解决方案1】:

    您必须将“e”的值作为参数传递给另一个函数。 JavaScript 中的作用域是由函数的词法关系决定的,而不是动态关系。函数中的代码可以看到“向外”,并且从funcB() 移出不会遇到定义了“e”的范围。 funcB() 中的代码唯一可见的符号是它自己的局部符号(在本例中为 p)和全局符号。

    现在,您可以在对象本身上显式存储“e”的副本作为属性:

    return  function(e) {
        window.console.log('k: ' + k); // 'abc'
        window.console.log('e: ' + e); // 'def'
    
        that.e = e;
        return that.funcB(k);
    };
    
    Test.prototype.funcB = function (p) {
        window.console.log('p: ' + p); // 'abc'
        window.console.log('e: ' + this.e);
    }
    

    【讨论】:

    • 我也不想通过它。有没有办法使用闭包让funcB能够访问变量e?
    • 我想我明白你在说什么。由于 funcB 没有按词法包含在 funcA 中(它仅由 funcA 执行),因此不涉及闭包。
    • @ChrisG。是的,基本上。范围是静态的。
    • @ChrisG。答案已更新 - 将其作为参数传递的另一种方法是将其保存在对象上。
    • 除非有更好的主意,否则我会走这条路。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-04-11
    • 2012-08-12
    • 2017-01-04
    • 1970-01-01
    • 2017-06-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多