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.






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