2013-03-18 28 views
2

有很多问题和答案涵盖了这种技术,但我似乎无法找到所需的this上下文为call()或apply()设置。如何在Array.prototype.slice.call(参数)中设置'this'上下文

我明白

Array.prototype.slice.call(arguments)

是有点相当于

arguments.slice()

arguments被转换成一个适当的数组对象,但如果我尝试使用这个约定,我自己对象不起作用。我试着写一个小的测试这样做:

var Logger = function(){}; 
Logger.prototype.print = function(msg){ 
    console.log ((new Date()).getTime().toString() + msg); 
}; 

(function(){ 
    var o = { 
    name: "Hi Bob!", 
    }; 

    var l = new Logger(); 
    l.print(o.name); //works fine 
    Logger.prototype.print.call(o.name); //calls print method, but 'msg' is undefined 
}()); 

是否有可以Array.prototypearguments对象,允许该功能的应用程序没有必要的情况下工作,有些特别的问候?

+0

不,只有你的代码“有点相当于”'o.name.print()' - 这显然不是你想要的。有关它的工作方式,请参阅http://stackoverflow.com/q/6763555/1048572。 – Bergi 2013-03-18 16:07:57

回答

1

Logger.prototype.print打印任何地方都不会使用this变量,所以使用call()是毫无意义的。您的函数期望通过msg作为参数。这就是为什么l.print(o.name);有效。

正如你在你的问题说:

Array.prototype.slice.call(arguments) 

类似于arguments.slice()。因此:

Logger.prototype.print.call(o.name); 

o.name.print()类似。正如你所看到的,这是没有道理的。

如果你真的使用.call(),你可以这样类似:

Logger.prototype.print.call(null, o.name); 

但是,正如你所看到的,这是愚蠢的,而且更难不仅仅是l.print(o.name);阅读。

+0

根据你的回答进行一些进一步的测试,现在我明白了。 [http://jsbin.com/iwaric/1/edit](http://jsbin.com/iwaric/1/edit)。所以'arguments'参数实际上成为'slice()'的上下文,当不带参数调用时它会返回原始数组的副本。 – mastaBlasta 2013-03-18 16:04:32

+0

@mastaBlasta:是的,这有效。正如你所看到的,所有'。call()'does允许你在函数内部改变'this'(如果使用的话)。在你的情况下,我建议只需坚持'l.print(o.name);'。 – 2013-03-18 16:07:41

+1

我其实并没有这方面的用途。我刚刚读过一些使用'Array.prototype.slice.call(arguments)'的其他代码,然后继续探索call()如何处理看起来像“数组”的参数。回想起来,答案很明显 - 背景只是一个对象! – mastaBlasta 2013-03-18 16:10:13

2

slice和你的函数之间的区别是slice使用上下文(this),而你的函数只使用它的参数。

如果你真的想用call您的功能,用它作为

Logger.prototype.print.call(null, o.name); 

但是,你还不如用

Logger.prototype.print(o.name); 
相关问题