javascript中对函数的间接引用

javascript中对函数的间接引用,javascript,Javascript,我正在读kyle simpson写的《你不知道JS》这本书,突然发现下面的代码有点让我困惑。基本上我是在读一个关于这个关键字的主题。以下是片段: function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; o.foo(); // 3 (p.foo = o.foo)(); // 2 到目前为止,阅读这本书,我确实明白这是如何工作的,但对我来说,很难理

我正在读kyle simpson写的《你不知道JS》这本书,突然发现下面的代码有点让我困惑。基本上我是在读一个关于
这个
关键字的主题。以下是片段:

function foo() {
    console.log( this.a );
}

var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2
到目前为止,阅读这本书,我确实明白这是如何工作的,但对我来说,很难理解片段最后一行到底发生了什么

如果我自己分析,最后一行是在全局范围内执行的iffe,如果在iffe中执行foo()函数,则foo()函数中的this.a将指向全局范围内的a,实际上是2

但不知何故,我觉得我不完全明白最后一行发生了什么,有人能帮我把它分解一下吗

多谢各位


Alexander。

最后一行是传递对
foo
函数的引用,然后在全局范围内执行,如您所见。相当于这个

var f = p.foo = o.foo;
f();

赋值的返回值始终是值本身。在本例中,返回值是对函数foo的引用。因此,在一行上执行两个步骤

  • p.foo=o.foo
  • foo()

  • 这就是正在发生的事情:

    时(p.foo=o.foo)()时,JS将其转换为

    function foo() {
      console.log( this.a );
    }
    
    由于在全局范围内设置了
    var a=2
    ,并且没有向函数传递任何内容,因此您的结果是
    2

    那么问题是为什么JS将
    (p.foo=o.foo)
    转换成
    foo()
    函数

    如果你把它分解,你会发现:

    p.foo=o.foo
    :这是从右向左分配变量。就像
    var a=“something”
    这意味着现在,
    p.foo
    等于
    o.foo
    ,既然
    o.foo
    等于
    foo
    ,我们现在说的是
    p.foo=foo
    ,换句话说:
    (p.foo=o.foo)()
    (foo)(
    相同,后者随后运行
    foo
    函数

    进一步解释:

     console.log(p.foo); //returns undefined because nothing was set to it
     console.log(o.foo); //returns foo, because it was assigned var o = {foo: foo};
     p.foo = o.foo; // this assignes foo to p.foo
     console.log(p.foo); //returns foo, it is no longer undefined, because of our assignment
     (p.foo)(); // will run the function
    


    我以前在获取未定义的
    时遇到问题,但那是因为我运行的测试阻止我正确访问我的函数。

    到底缺少什么?赋值表达式的值就是赋值。顺便说一句,这似乎是为了混淆而不是教导…赋值的返回值总是值本身。因此,在一行上执行两个步骤。1. <代码>p.foo=o.foo2<代码>foo()在chrome中我得到
    3,未定义
    在a中。同意@SpencerWieczorek,在FF 31.4中我得到了相同的结果:
    3,未定义
    当我说
    (p.foo=o.foo)(;//2
    因此基本上p.foo取o.foo()的值,由于这是一个iffe,p.foo()将必须在全局范围内执行,我猜打印4也是如此?不,在赋值过程中没有调用该函数。您正在将函数用作变量。因此,在这个操作之后,p.foo和o.foo都引用了全局范围中定义的方法foo()。赋值实际上并不调用该方法。赋值返回被赋值的值,这样您就可以执行
    c=(a=b)
    ,并且所有值都将相等
    c
    。因为被分配的是foo函数,所以这就是在最后被调用的。如果在我们的示例中c代表foo(),则在这一行中<代码>(p.foo=o.foo)(;//2
    我是否显式调用foo。最后的
    ()
    调用赋值的结果,即foo