如何在Array.prototype.slice.call(arguments)中设置'this'上下文

时间:2013-03-18 15:50:39

标签: javascript

有很多问题和答案都涵盖了这种技术,但我似乎找不到如何为call()或apply()设置所需的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对象是否有一些特殊的东西允许函数应用程序在没有必要的上下文的情况下工作?

2 个答案:

答案 0 :(得分:2)

slice与您的函数之间的区别在于slice使用上下文(this)而您的函数仅使用其参数。

如果您真的想在功能中使用call,请将其用作

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

但你不妨使用

 Logger.prototype.print(o.name);

答案 1 :(得分: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);更难阅读。