根據javascript高級程序設計第三版 “事實上,傳遞參數並非apply()和call()真正用武之地,他們真正強大的地方是能夠擴充函數賴以運行的作用域“ && “擴充作用域的最大好處,就是對象不需要與方法有任何耦合關係”
Chapter 1
//A有方法,B沒有,通過call B可以引用A的方法
function cat(){
}
cat.prototype={
food:"fish",
say: function(word){
alert("I love "+this.food+" and talk "+word);
}
}
var blackCat = new cat;
//blackCat.say('miaomiao');
var whiteDog = {food:"bone"}
blackCat.say.call(whiteDog,'wangwang');
//blackCat.say.apply(whiteDog,['wangwang']);
這裏blackCat繼承了Cat的say方法,而whiteDog如果在不想定義say方法的情況下使用,就需要call的出現了,這裏whiteDog可是引用到blackCat的say方法
Chapter 2
// call實現繼承
var Parent = function(){
this.name = "yjc";
this.age = 22;
}
var child = {};
console.log(child);//Object {} ,空對象
Parent.call(child);
console.log(child); //Object {name: "yjc", age: 2}
通過call來實現屬性的繼承
Chapter 3
// call將參數轉爲數組
function exam(a, b, c, d, e) {
// 先看看函數的自帶屬性 arguments 什麼是樣子的
console.log(arguments);
// 使用call/apply將arguments轉換爲數組, 返回結果爲數組,arguments自身不會改變
var arg = [].slice.call(arguments);
console.log(arg);
}
exam(2, 8, 9, 10, 'guguji');
// result:
// { '0': 2, '1': 8, '2': 9, '3': 10, '4': 'guguji','length':5 }
// [ 2, 8, 9, 10, 3 ]
[].slice.call()這種方法可以將帶有length的key爲自然數的json轉換爲數組,也常常使用該方法將DOM中的nodelist轉換爲數組。
[].slice.call( document.getElementsByTagName('li')
call和apply功能相同,只是寫法不一樣而已。
fun.call(this,1,2,'dukuan');
fun.apply(this,[1,2,'dukuan']);//參數以數組的方式傳入
e.g. Math.max(a,b,…,x,y)函數用於取若干值(不是隻能比較兩個)中的最大值,所以求一個數組中([1,4,5,2,65,7,5])的最大值可以藉助apply
var arr=[1,2,2,1,4,5,6,6,8,9,55];
var Max=Math.max.apply(null,arr);//最大值爲55
bind vs call,apply
MDN bind的定義是:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
bind方法創建一個新函數,當被調用時會改變this的值以及傳入一串新函數調用的預設參數。
偶發現bind和call,apply的一個不同是bind會返回一個新函數並且帶有一些預設參數(不會執行)而call,apply會調用這個函數。
bind的兩大功能,改變this和預設參數。
爲了兼容低版本瀏覽器bind可以重寫:
Function.prototype.Bind = function(index){
var that = this;
var arg = Array.prototype.slice.call(arguments,1)
return function(){
var arg1 = Array.prototype.slice.call(arguments);
that.apply(index,arg.concat(arg1))
}
}