这个JavaScript代码中使用了什么技术?

时间:2011-02-13 20:52:03

标签: javascript

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。

3 个答案:

答案 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.fooa.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);