为什么要使用这个obj.method.call(obj,arg)而不是obj.method(arg)?

时间:2015-06-15 05:41:48

标签: javascript

我有时会看到这种模式......

obj.method.call(obj, arg)  

我不明白为什么它与......不同。

obj.method(arg)  

为什么要使用第一种模式?

我的善良,似乎引起了很多讨论:)

只是为了澄清,我只询问当方法所在的对象与call()的第一个参数相同时的情况(或者@FelixKling将它更好:当所有者时接收器相同。我不是在问obj.method.call(obj2, arg)

如下所述,即使绑定函数的情况也无法区分这两种方法。

o2={p2:3};
o={p1:(function(){return this.p2}).bind(o2), p2:2};
o.p1() === o.p1.call(o) // true  

修改

我想这个成语的来源是用来重新绑定对象方法的模式...

obj.method.apply(obj, arguments)

3 个答案:

答案 0 :(得分:3)

您发布的示例没有区别。但是,obj1.method.call(obj2, arg)允许您更改方法内的thisobj.method.apply(obj, args)允许你有变量参数计数。

例如,[].slice.call(arguments)(及其上级Array.prototype.slice.call(arguments))是从非数组(slice)接收器上的数组调用arguments的常用习惯用法。

答案 1 :(得分:2)

  

为什么要使用此obj.method.call(obj, arg)而非obj.method(arg)

没有实际的理由这样做。

在这两种情况下,this都会引用obj,假设函数没有绑定到不同的值(在这种情况下,this始终是绑定值)。

答案 2 :(得分:-2)

如果方法中的第一个模式this变量将指向obj变量:

obj.method.call(obj, arg)

第二种情况下的变量this将指向父变量,主要是window变量。 您可以在控制台中检查是否执行以下操作:

var
  num = 1,
  pass = "Test",
  myFunc = function(expArg) {
    console.log(expArg);
    console.log(this);
  };

myFunc(pass);
// You would get "Test" and reference of window variable
myFunc.call(num, pass);
// You would get "Test" and number object with value of 1.