標籤:
apply()和call()都是屬於Function.prototype的一個方法。是JavaScript引擎內在實現的,因為屬於Function.prototype,所以每個Function對象執行個體,也就是每個方法都有call, apply屬性.既然作為方法的屬性,那它們的使用就當然是針對方法的了.這兩個方法是容易混淆的,因為它們的作用一樣,只是使用方式不同.
相同點:兩個方法產生的作用是完全一樣的
不同點:方法傳遞的參數不同
用途都是在特定的範圍中調用函數,實際上等於設定函數體內this對象的值。
apply:方法能劫持另外一個對象的方法,繼承另外一個對象的屬性.
- Function.apply(obj,args)方法能接收兩個參數
- obj:這個對象將代替Function類裡this對象
- args:這個是數組,它將作為參數傳給Function(args-->arguments)
- function的方法應用到obj上?
- call, apply作用就是借用別人的方法來調用,就像調用自己的一樣.
call()方法與apply()方法的作用相同,它們的區別僅在於接受參數的方式不同,它的第二個參數是一個參數列表,在使用call()時,傳遞的參數必須逐個列出來。 apply()執行個體:
1 function Person(name,age){ 2 this.name = name; 3 this.age age; 4 } 5 function Student(name,age,grade){ 6 Person.apply(this.arguments); 7 this.grade = grade; 8 } 9 var student = new Student("123‘,12,"三年級");10 alert("name:"+student.name+"age:"+student.age+"grade:"+student.grade);11 //name:123 age:12 grade:三年級
分析:Person.apply(this,arguments);this:在建立這個對象的時候代表的是studentarguments:["123‘,12,"三年級"];換句話說就是:用student去執行Person這個類裡面的內容在Person 這個類裡面存在this.name等之類的語句,這樣就將屬性建立到了student對象裡面。 call()的執行個體:Person.call(this,name,age); 兩者的選擇:取決於採取哪種給函數傳遞參數的方式最方便。如果打算直接傳入arguments對象,或者函數中先接受到的也是一個數組,那麼用apply()肯定更方便,否則選擇call(); 一些應用:
1.Math.max:
1 var value = [1,2,3,4,5,6,7,8,9];2 3 var max = Math.max.apply(Math.value);
把Math對象作為apply()的第一個參數,從而正確設定this 的值,然後可以將任何數組作為第二個參數。 (因為Math.max 參數裡面不支援Math.max([param1,param2]) 也就是數組,但是它支援Math.max(param1,param2,param3…),所以可以根據剛才apply的那個特點來解決 var max=Math.max.apply(null,array),這樣輕易的可以得到一個數組中最大的一項(apply會將一個數組裝換為一個參數接一個參數的傳遞給方法)這塊在調用的時候第一個參數給了一個null,這個是因為沒有對象去調用這個方法,我只需要用這個方法幫我運算,得到返回的結果就行,.所以直接傳遞了一個null過去 )
2.Array.prototype.push同樣push方法沒有提供push一個數組,但是它提供了push(param1,param,…paramN) 所以同樣也可以通過apply來裝換一下這個數組,即:
1 var arr1 = new Array("1","2","3");2 3 var arr2 = new Array("4","5","6");4 5 6 7 Array.prototype.push.apply(arr1,arr2);
也可以這樣理解,arr1調用了push方法,參數是通過apply將數組裝換為參數列表的集合.
3.Array.prototype.slice.call(arguments)//能將具有length屬性的對象轉換成數組。(附數群組轉換通用函數):
1 var toArray = function(s){ 2 try{ 3 return Array.prototype.slice.call(s); 4 }catch(e){ 5 var arr = []; 6 for(var i = 0, len = s.length; i< len;i++) 7 arr[i] = s[i];(arr.push(s[i])) 8 return arr; 9 }10 }
apply()和call()的真正用武之地是能夠擴充函數賴以啟動並執行範圍
1 window.color = "red"; 2 var o = {color:"blue"}; 3 4 function sayColor(){ 5 alert(this.color); 6 } 7 8 sayColor();//red 9 sayColor.call(this);//red10 sayColor.call(window);//red11 sayColor.call(o);//blue
使用call()或者apply()來擴從範圍的最大好處,就是對象不需要與方法有任何耦合關係。
bind()這個方法會建立一個函數的執行個體,其this值會被綁定到傳給bind()函數的值。
1 window.color = "red"; 2 var o = {color:"blue"}; 3 4 function sayColor(){ 5 alert(this.color); 6 } 7 8 sayColor();//red 9 sayColor.call(this);//red10 sayColor.call(window);//red11 sayColor.call(o);//blue
apply() 和 call()