var a = (function(y,x) {
var x = null;
return {
foo: function(x){ return this.bar(x * y); },
bar: function(x){ return x + y; }
}
})(3,4);
请有人帮我解释一下上面的代码究竟发生了什么?我在哪里可以阅读或参考高级JavaScript技术?对不起,我刚开始学习JavaScript。
答案 0 :(得分:6)
这是一个关闭。
创建匿名函数,然后立即执行,并将其返回值分配给a
。
传递给它的变量(或多或少)无法被其他函数干扰。
出于某种原因,x=4
会立即被外部函数中的x=null
覆盖。然后在每个内部函数的参数中再次覆盖。这使得首先传递它毫无意义。
答案 1 :(得分:1)
发生的事情是你创建了一个带有2个参数x和y的匿名函数。匿名函数立即执行。
它创建一个局部变量x
并将其赋值为null。这在这个例子中绝对没有任何意义。 ,用于演示参数x覆盖本地实例化的x,并且只能使用 this
关键字进行访问。
匿名函数然后返回一个具有属性foo和bar的对象,这两个函数都是参数x
。
最有趣的是来自匿名函数的参数y
在foo和bar函数中变为“锁定”,因此当你调用时:
a.foo(4); // output 15
a.foo(2); // output 9
在上面的例子中,4作为x
参数传递给函数foo。 4和3的乘积(匿名函数中传递的原始y
值)为12.此产品被传递到bar函数,其中12被添加到相同的锁定y
值3,它给你15的总和。
foo(2)也会发生同样的过程。
我的建议是使用Firebug启动Firefox并将该代码粘贴到控制台并运行它。然后使用不同的值调用a.foo
和a.bar
并跟踪执行情况。这将有助于您更好地了解代码中发生的事情。
使用替换功能执行细分:
a.foo(4);
function(4) { return this.bar(4 * 3); }
function(4) { return function(4 * 3) { return (4 * 3) + 3; } };
function(4) { return function(12) { return (12) + 3; } };
function(4) { return function(12) { return 15; } );
function(4) { return 15; }
15
我还建议你查看this example of closures,但没有匿名功能。删除匿名组件可能有助于使其更加清晰。
事实上,这是你上面的例子,但是没有匿名函数:
function fooBar(y,x) {
var x = null;
return {
foo: function(x){ return this.bar(x * y); },
bar: function(x){ return x + y; }
}
}
var b = fooBar(3,4);
b.foo(2); // output 9
b.foo(4); // output 15
所以在上面的例子中,fooBar(3,4)
返回一个包含两个函数foo和bar的对象,其中3被锁定为y
参数。
JavaScript Kit - Closures 101. They're Not Magic,是另一个很好的资源,可以帮助解释闭包的目的,以及它在幕后的意义。
答案 2 :(得分:0)
请参阅http://jibbering.com/faq/notes/closures/ - 它以可读的方式解释详细信息。
这种“双重绑定”是必需的,因为只有新的函数作用域引入了新的执行上下文(请参阅上面的链接,了解这意味着:-)这就是ECMAScript的工作方式 - 语言像C,Java或C#,每个新的块[一般来说]引入了一个新的词法变量范围。
修改(仔细检查):
var a = (function(y,x) {
// This is a new function body, so it introduces a new lexical scope
// The following line is questionable. Function parameters always belong to
// the function scope. It has the same effect a `x = null` (no var) here
// but since it just discards the value, is still questionable...
var x = null;
return {
// Both of these functions have their own function scope and
// since they are created here they can "bind" to free variables
// in the enclosing scope through the [[scope]] chain (implicitly).
// Inside the x refers to the parameter passed in, respectively
// and does NOT refer to the x above.
foo: function(x){ return this.bar(x * y); },
bar: function(x){ return x + y; }
}
})(3,4);
// Then the function is executed which results in the object that contains
// foo and bar properties which contain functions that "close over" y.
具有相同语义的清理版本,以显示哪些变量绑定真正发生
var a = (function(y,__ignored) {
return {
foo: function(x){ return this.bar(x * y); },
bar: function(x){ return x + y; }
}
})(3,4);