call apply

伪原创。

我也是靠别人解答才理解的。自己用了一些例子来帮助理解。跟大家交流一下。

看例子:

var a = Function.prototype.call.apply(function(a){return a;}, [0,4,3]);alert(a);

输出4 。  为什么呢?

看例子来解答:

例子1:

  var p = Function.prototype;
  var obj = function (a) {return a;};
  document.write(p.call.apply(obj,[1,3,4]));  //输出 3
p.call.apply(obj,[1,3,4]) 等价于 obj.call(1,3,4)

例子2:

   function a() {
       this.add = function() {return arguments[0] + arguments[1];};
   }
  var p = new a();
  var obj = function (a) {return a;};
  document.write(p.add.call.apply(obj,[1,3,4]));   //输出3

p.add.call.apply(obj,[1,3,4])等价于obj.call(1,3,4) 

例子3:

   function a() {
       this.add = function() {return arguments[0] + arguments[1];};
   }
  var p = new a();
  var obj = function (a) {return a;};
  document.write(p.add.apply(obj,[1,3,4]));  //输出4

p.add.apply(obj,[1,3,4])等价于 obj.add(1,3,4)  add()方法是函数a 的 add方法.

例子4:

  function a() {
       this.add = function() {return arguments[0] + arguments[1];};
   }
  var p = new a();
   document.write(p.add.call(1,2,3));  //输出5  当call方法里()都是参数的时候 p.add(2,3)

例子5:

  function a() {
       this.add = function() {return arguments[0] + arguments[1];};
   }
  var p = new a();
  var obj = function (a) {return a;};
  document.write(p.add.call(obj,1,3,4));    //输出4  当call方法里()带obj或func时,obj.add(1,3,4)


总结,对于A.方法1.apply(B,array) 实际上等价于B.方法1(arr[0],arr[1],.....) 

对于A.方法1.call(B,arg1,arg2,...) 实际上等价于 B.方法1(arg1,arg2,...)   值得注意的是,call的另类使用A.方法1.call(arg1,arg2,...) ,等价于A.方法1(arg2,....)


上面的例子,由论坛qwklove给出的讲解:

首先,把Function.prototype.call当成一个整体来看,它本身也是一个函数,因此和其他函数一样:具有apply方法。
其次,call.apply(fun,[arg1,arg2,...])=fun.call(arg1,arg2,...)
所以,按照这两个条件把上面的语句分解后可得到:
var a=  function(a){return a;} .call (0,4,3);//fun.call()中的参数除第一个外,余下的为传入fun的参数。因此,在这里,4和3为传入function(a){return a}的参数,因为该匿名函数只需一个参数,因此按顺序只选到4做参数。


这里附上ecma-262 docs里对于Function.prototype.call 和Function.prototype.apply的描述.


Function.prototype.apply (thisArg, argArray)
When the apply method is called on an object func with arguments thisArg and argArray, the following steps are taken:
1. If IsCallable(func) is false, then throw a TypeError exception.
2. If argArray is null or undefined, then
a. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and an empty list of arguments.
3. If Type(argArray) is not Object, then throw a TypeError exception.
4. Let len be the result of calling the [[Get]] internal method of argArray with argument "length".
5. Let n be ToUint32(len).
6. Let argList be an empty List.
7. Let index be 0.
8. Repeat while index < n
a. Let indexName be ToString(index).
b. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the argument.
c. Append nextArg as the last element of argList.
d. Set index to index + 1.
9. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and argList as the list of arguments.
The length property of the apply method is 2.
NOTE The thisArg value is passed without modification as the this value. This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.


15.3.4.4 Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )
When the call method is called on an object func with argument thisArg and optional arguments arg1, arg2 etc, the following steps are taken:
1. If IsCallable(func) is false, then throw a TypeError exception.
2. Let argList be an empty List.
3. If this method was called with more than one argument then in left to right order starting with arg1 append each argument as the last element of argList
4. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and argList as the list of arguments.
The length property of the call method is 1.
NOTE The thisArg value is passed without modification as the this value. This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章