简体   繁体   English

关于javascript关闭的困惑

[英]Confusion regarding javascript closure

While developer a client side application I ran into an error that I believe is related to my incomplete understanding of use of closures. 虽然开发人员是客户端应用程序,但我遇到了一个错误,我认为这与我对闭包使用的不完全理解有关。 I have trimmed down my code to the following : 我已将我的代码修改为以下内容:


var fn1 = function(arr){ 
  return function(val){ 
    var idx;
    var x = 20; 
    for (idx in arr) {
      arr[idx]();
    } 
  } 
}

var fn2 = fn1([function(){
  x+= 20; 
  alert(x);
}])

Now upon executing : 现在执行:


fn2()

I receive an error : ReferenceError: reference to undefined property "x" 我收到一个错误: ReferenceError: reference to undefined property "x"

I would like to know why this error is arising and why can't fn2 access the variables defined in the local scope of closure function returned by fn1 ? 我想知道为什么会出现这个错误,为什么fn2不能访问fn1返回的本地闭包函数范围内定义的变量?

In short: closures have access to parent scopes in relation to where they were declared , not where they are used. 简而言之:闭包可以访问与声明它们的位置相关的父作用域,而不是它们的使用位置。

The function returned by fn1 has access to the scope of its parent function ( fn1 itself), ie, it has access to arr . fn1返回的fn1可以访问其父函数( fn1本身)的范围,即它可以访问arr But the functions inside your array do not have access to variables defined within fn1 or within the function returned from it, because those functions (inside array) were declared in a different scope. 但是数组中的函数无法访问fn1定义的变量或从它返回的函数内,因为这些函数(在数组内部)是在不同的范围内声明的。

Regarding the actual problem you're trying to solve with that code, I'm not sure if I understood it correctly. 关于你试图用该代码解决的实际问题,我不确定我是否正确理解它。 Looks like you're trying to apply some functions to a certain number. 看起来你正在尝试将某些功能应用于某个数字。 I don't understand why that number ( 20 in your example) is a constant and not a parameter. 我不明白为什么这个数字(在你的例子中是20 )是常数而不是参数。 Here is my proposed solution for that (no closures!): 这是我提出的解决方案(没有关闭!):

var applyArrayFunctions = function(arr, x){ 
    for(var i=0; i<arr.length; i++) {
        x = arr[i](x);
    }
    return x;
}

var num = 2;
var fnArray = [
    function(val){
      return val + 20; 
    },
    function(val){
      return val * 2; 
    }
];

console.log(applyArrayFunctions(fnArray, num));​ // logs 44​​​

I suspect the error is in the line x+=20 我怀疑错误在x+=20

var x = 20 only exists inside the scope of the anonymous function returned by fn1 . var x = 20仅存在于fn1返回的匿名函数的范围内。 x+=20 evaluates before fn1 does, so x doesn't even exist at that time. x+=20fn1之前进行求值,因此x在那时甚至不存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM