我在浏览器的控制台做了一个JavaScript实验-
首先,我创建了一个新对象foo,如下所示
var foo = {
bar: function() { return this.baz; },
baz: 1
};现在,当我在控制台中再次运行以下代码时,它将返回"number"
(function(){
return typeof foo.bar();
})();但是,当我运行以下匿名函数时,它返回"undefined"
(function(){
return typeof arguments[0]();
})(foo.bar);据我所知,在上面的函数中,arguments[0]返回foo.bar (下面的例子也证明了),那么为什么上面的代码返回"undefined"而不是"number"
当我跑的时候
(function(){
return arguments[0];
})(foo.bar);返回function () { return this.baz; }
也是
(function(){
return typeof arguments[0];
})(foo.bar());返回"number"为什么不
(function(){
return typeof arguments[0]();
})(foo.bar);还是一样的?在JavaScript中有什么基本定律在这里起作用吗?
发布于 2013-12-16 04:19:52
this取决于如何调用函数。当使用点表示法时,JavaScript将this的上下文设置为接收方。在您的示例中,没有接收方,而是对函数的引用,因此您丢失了上下文。您必须显式传递它:
arguments[0].call(foo);arguments[0]是与foo.bar相同的函数对象,但是this的值是动态的。在foo.bar()中,this被分配给foo,因为您使用了foo. (点符号)。但是在arguments[0]()中没有点(没有接收者),所以this是默认值,也就是window。
这是相同的函数,但调用不同。
发布于 2013-12-16 04:30:37
详细阐述艾尔克罗的回答。
foo.bar是一种方法,是关于如何做某事的指导。在面向对象的编程语言中,唯一可以使用该指令的对象是foo或与foo相关的对象;但是在JavaScript中,任何人都可以尝试运行它,如果代码要求的话。
在第二个匿名函数中,您将获得一个要运行的方法,运行它,并返回结果的类型。但是,运行这个函数的不是foo;它是匿名的,所以window是运行它的对象。window运行foo,它试图返回this.baz;然而,window没有baz,这就是为什么没有定义的原因。
要进一步测试它,请尝试设置window.baz并查看您是否得到了正确的结果,还尝试了elclanrs关于使用call()方法来确保从foo的作用域调用它的建议。
编辑
没错,arguments[0]和foo.bar的类型是相同的;它们都是“函数”。我认为,对于JavaScript将函数作为头等对象的处理,存在混淆之处。
如果您熟悉像Java或C++这样的面向对象语言,那么当您调用bar时,它总是被具有baz属性的foo调用;然而,在JavaScript中并非如此。任何函数都可以被任何对象调用,这意味着结果可能有意义,也可能没有意义。
正如埃克尼尔斯所说,这两者之间的区别在于.。假设我创建了自己的对象phew = {baz: 44}。我可以有效地从foo中“偷”一种方法:phew.myMethod = foo.bar。现在,phew知道bar中包含的指令,如果我调用phew.myMethod(),我的结果将是44,因为phew正在调用该方法,而phew的baz是44;在哪里定义该方法并不重要!重要的是该方法要做什么,而bar要求返回调用它的人的baz。
现在,回到您的代码,您正在调用arguments[0]()。看起来应该是一样的,但是因为函数是一流的对象,所以当您将它作为参数传递时,您真正传递的只是一个名为bar的函数。当您调用arguments[0]()时,它就像调用bar()一样,这与调用foo.bar()不同,就像调用phew.myMethod()、一样,尽管它们都是完全相同的函数。
有关更多信息,请访问this SO post
https://stackoverflow.com/questions/20603381
复制相似问题