2017-08-08 71 views
2

由于关闭是绑定到它的功能是词法环境我不知道为什么notAClosure建设不是一个封闭:为什么这不是一个闭合

let a = { b: 42 }; 
let notAClosure = (param) => { param.b++ }; 
let aClosure =() => { a.b++ }; 
notAClosure(a); 

notAClosure调用,我们传递给它的参考对象a。这意味着现在在关闭内部,我们可以访问外部范围=词法环境。 我的功能是否正确?是aClosure真正的关闭?是否notAClosure真的不是封闭,如果是正确的 - 那为什么?

+2

函数只在访问在外部作用域中定义的变量时才形成闭包。 'param'是一个局部变量,所以'notAClosure'不是一个闭包。所有的函数都可以访问全局变量,所以如果'a'是全局的,'aClosure'实际上不是一个闭包。 – 4castle

+1

为什么这对你很重要?有没有一个真实世界的场景,你的代码有差异?这似乎纯粹是哲学的。 – Graham

回答

1

您的变量命名是正确的。

notAClosure的函数体实际上并没有引用任何超出其范围的内容。函数aClosure确实指的是它自己范围之外的变量,即a

a传递给notAClosureby-value-by-reference。由于param是一个参数,所以在notAClosure的函数体的直接范围内放置了一个“值”参考a

aClosure之内,在本地范围内没有a;相反,该功能是(强制)参考外部范围中的a。稍微复杂一些的例子,使其更显而易见的,为什么它成为一个封闭:

let x = (function() { 
    let a = { b: 42 }; 
    return() => { a.b++; }; 
})(); 

x被分配到立即返回另一个函数的函数。 x在隐藏返回的lambda函数中“隐藏”a。它是不可能以任何方式访问a而不会调用x,但a仍然存在于内存中,因为它可以在外部范围内访问,因此可以在返回的lambda范围内访问。

0

你的函数aClosure简单地访问通过全球范围内的a变量,因此,它不是一个封闭,你可以看到它实际上在这个例子修改a.b值:

let a = { b: 42 }; 
let aClosure =() => { a.b++ }; 

console.log(a.b); //42 
aClosure(); 
console.log(a.b); //43 

,如果你想了解关闭最好我推荐this book

+0

您能否引用任何包含“全局”术语的封闭定义?如果否,那么外部范围的全局性对理解闭包有什么作用? – zeliboba

+0

对不起,如果我错了,但是当函数,回调函数或类似函数可以访问它自己的值时会发生闭包。在这里我展示了由于'aClosure()'修改全局范围内的a.b的值,它不是闭包。 –