允许'p.foo=o.foo'返回对函数'foo'的引用的javascript机制/规则是什么?
我目前正在学习javascript,学习《你不知道js》系列 在“this&objectprototype”一节中,在讨论“函数的间接引用”时,作者指出 赋值表达式p.foo=o.foo的结果值为 仅引用底层函数对象。因此 有效的调用站点只是foo(),而不是像您可能看到的p.foo()或o.foo() 期待。根据上述规则,默认绑定规则适用允许'p.foo=o.foo'返回对函数'foo'的引用的javascript机制/规则是什么?,javascript,function,this,indirection,Javascript,Function,This,Indirection,我目前正在学习javascript,学习《你不知道js》系列 在“this&objectprototype”一节中,在讨论“函数的间接引用”时,作者指出 赋值表达式p.foo=o.foo的结果值为 仅引用底层函数对象。因此 有效的调用站点只是foo(),而不是像您可能看到的p.foo()或o.foo() 期待。根据上述规则,默认绑定规则适用 显然,(p.foo=o.foo)返回对函数foo的引用。但是允许(p.foo=o.foo)返回对函数foo的引用的机制/规则是什么?换句话说,为什么简单赋值
显然,
(p.foo=o.foo)
返回对函数foo
的引用。但是允许(p.foo=o.foo)
返回对函数foo
的引用的机制/规则是什么?换句话说,为什么简单赋值返回对foo
函数的引用 当我想理解这样的事情时,我发现一步一步地把它分解是很有帮助的
o.foo
查看o
对象并找到名为foo
的属性。它返回对该属性的引用,不管它是什么。在这种情况下,o.foo
属性是对函数foo
的引用p.foo=o.foo
获取上面的结果(对函数foo
的引用),在p
对象中创建一个属性,该属性也被命名为foo
。因此现在p.foo
也是对foo
函数的引用,与o.foo
完全相同=
符号或p.foo
左侧的内容,它(作为提醒)仍然是对foo
函数的引用()
。这将调用我们目前手头的任何函数。这就是foo
函数。请特别注意,我们没有调用p.foo()
。这将是对p.foo
作为引用的函数的方法调用,因此在该函数中,this
将设置为p
。但我们没有这样做。我们只是调用(p.foo=o.foo)
返回的任何函数。与以前一样,这是相同的foo
函数,但现在我们已经失去了它与o
对象或p
对象的任何连接foo
函数,而没有对任何特定对象设置this
。因此,当我们进行调用时,this
被设置为undefined
严格的模式下运行,所以JavaScript“有益地”不想给我们一个未定义的this
,所以它将this
设置为浏览器中的窗口
对象或节点中的全局
对象
var a=2代码>。因此窗口
或全局
对象实际上现在有一个名为a
的属性,该属性的值是2
console.log(this.a)
时,我们从窗口
或全局
对象中选择a
属性。该值为2
功能测试(){
函数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,但现在未定义
}
test()代码>赋值运算符=
是JavaScript中生成(返回)赋值的表达式。因为它是一个表达式,所以可以在任何允许表达式的地方使用,例如括号内
例如:
let test = (a = b = c = { name: 'test' })
上面的代码首先计算括号中的表达式,并将变量c
、b
和a
指向测试对象(按该顺序),然后将test
指向该表达式产生的值。执行该行后,a
、b
、c
和test
都将指向同一对象
同样地
(p.foo = o.foo)
将产生o.foo
返回(从技术上讲,它将产生o.foo
指向的任何内容,即函数foo
)
至于
(p.foo = o.foo)()
通过在parenths之后添加额外的()
,我们告诉引擎我们想要调用表达式(p.foo=o.foo)
最终生成的任何内容。因此,我们最终调用函数foo
一个有用的重写方法是将上面的一行想象成这样:
let produced = (p.foo = o.foo)
produced()
.我正要发布一个不完整的答案,基本上你的第8步不见了。谢谢你理解了我不太明白的地方。我知道这是窗口,但不知道为什么。向上投票:-)实际上,在步骤5中,这个
被专门作为未定义的
传递。第8步是不相关的-它与呼叫类型无关。在第6步中,sloppy mode函数将此
值强制转换为一个对象,并用全局对象替换null
或未定义的
。@CaptainAmerica是的,它们是相同的。在这两种情况下,您都得到了对foo
函数的引用,然后直接将其作为函数调用,而不是作为方法调用。@CaptainAmerica多年的StackOverflow经验:-)我将重新措辞:如果最后一行是var q=o.foo,理解起来会不会更简单;q();//2
?这意味着o.foo
返回foo()
,并将q
转换为一个代理,而不带括号
let produced = (p.foo = o.foo)
produced()