Function.prototype.call()
call() 方法在使用一個指定的this值和若干個指定的參數(shù)值的前提下調(diào)用某個函數(shù)或方法.
fun.call(thisArg[, arg1[, arg2[, ...]]])
-
參數(shù)
- thisArg
- 在fun函數(shù)運行時指定的this值巾乳。需要注意的是您没,指定的this值并不一定是該函數(shù)執(zhí)行時真正的this值,如果這個函數(shù)處于非嚴(yán)格模式下胆绊,則指定為null和undefined的this值會自動指向全局對象(瀏覽器中就是window對象)氨鹏,同時值為原始值(數(shù)字,字符串压状,布爾值)的this會指向該原始值的自動包裝對象仆抵。
- arg1, arg2, ...
- 指定的參數(shù)列表。
- thisArg
-
返回值
- 返回結(jié)果包括制定的this值和參數(shù)种冬。
-
描述
- 可以讓call()中的對象調(diào)用當(dāng)前對象所擁有的function镣丑。你可以使用call()來實現(xiàn)繼承:寫一個方法,然后讓另外一個新的對象來繼承它(而不是在新對象中再寫一次這個方法)娱两。
function Product(name, price) {
this.name = name;
this.price = price;
if (price < 0) {
throw RangeError('Cannot create product ' +
this.name + ' with a negative price');
}
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
//等同于
function Food(name, price) {
this.name = name;
this.price = price;
if (price < 0) {
throw RangeError('Cannot create product ' +
this.name + ' with a negative price');
}
this.category = 'food';
}
//function Toy 同上
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
Function.prototype.apply()
apply() 方法在指定 this 值和參數(shù)(參數(shù)以數(shù)組或類數(shù)組對象的形式存在)的情況下調(diào)用某個函數(shù)莺匠。
fun.apply(thisArg[, argsArray])
- 參數(shù)
- thisArg
- 在 fun 函數(shù)運行時指定的 this 值。需要注意的是十兢,指定的 this 值并不一定是該函數(shù)執(zhí)行時真正的 this 值趣竣,如果這個函數(shù)處于非嚴(yán)格模式下,則指定為 null 或 undefined 時會自動指向全局對象(瀏覽器中就是window對象)旱物,同時值為原始值(數(shù)字期贫,字符串,布爾值)的 this 會指向該原始值的自動包裝對象异袄。
- argsArray
- 一個數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為單獨的參數(shù)傳給 fun 函數(shù)玛臂。如果該參數(shù)的值為null 或 undefined烤蜕,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開始可以使用類數(shù)組對象迹冤。
- thisArg
- 描述
- 在調(diào)用一個存在的函數(shù)時讽营,你可以為其指定一個 this 對象。 this 指當(dāng)前對象泡徙,也就是正在調(diào)用這個函數(shù)的對象橱鹏。 使用 apply, 你可以只寫一次這個方法然后在另一個對象中繼承它堪藐,而不用在新對象中重復(fù)寫該方法莉兰。
Function.prototype.construct = function (aArgs) {
var oNew = Object.create(this.prototype);
this.apply(oNew, aArgs);
return oNew;
};
// 在全局Function上添加一個方法,對所有Function有效
// this 指向調(diào)用方法的對象
// oNew是以這個對象的原型為原型構(gòu)造出來的新對象礁竞,
// this.apply(oNew,aArgs) 調(diào)用this指向的函數(shù)對象糖荒,并把這個函數(shù)對象的this直線oNew,以aArgs里的成員作為函數(shù)的參數(shù)
// 這個方法返回這個新對象
function MyConstructor () {
for (var nProp = 0; nProp < arguments.length; nProp++) {
this["property" + nProp] = arguments[nProp];
}
}
// 聲明一個構(gòu)造函數(shù)模捂,并解析傳入的參數(shù)
var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);
// 調(diào)用構(gòu)造函數(shù)的construct()方法
// 這個方法首先以這個函數(shù)為原型構(gòu)造一個新對象oNew
// 再以oNew作為this指向捶朵,myArray里的元素作為參數(shù)調(diào)用這個函數(shù)
// 運行結(jié)果oNew {property0: 4, property1: "Hello world!", property2: false}
// 把這個對象返回蜘矢,賦值給myInstance
Function.prototype.bind()
bind()方法會創(chuàng)建一個新函數(shù),當(dāng)這個新函數(shù)被調(diào)用時综看,它的this值是傳遞給bind()的第一個參數(shù), 它的參數(shù)是bind()的其他參數(shù)和其原本的參數(shù).
fun.bind(thisArg[, arg1[, arg2[, ...]]])
參數(shù)
-
thisArg
- 當(dāng)綁定函數(shù)被調(diào)用時品腹,該參數(shù)會作為原函數(shù)運行時的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時红碑,該參數(shù)無效舞吭。
-
arg1, arg2, ...
- 當(dāng)綁定函數(shù)被調(diào)用時,這些參數(shù)加上綁定函數(shù)本身的參數(shù)會按照順序作為原函數(shù)運行時的參數(shù)句喷。
-
返回值
- 返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝
-
描述
- bind() 函數(shù)會創(chuàng)建一個新函數(shù)(稱為綁定函數(shù))镣典,新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標(biāo)函數(shù))具有相同的函數(shù)體(在 ECMAScript 5 規(guī)范中內(nèi)置的call屬性)。當(dāng)目標(biāo)函數(shù)被調(diào)用時 this 值綁定到 bind() 的第一個參數(shù)唾琼,該參數(shù)不能被重寫兄春。綁定函數(shù)被調(diào)用時,bind() 也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)锡溯。一個綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器赶舆。提供的 this 值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)祭饭。
bind 兼容寫法
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1), //獲取第二個起的函數(shù)參數(shù)
fToBind = this, //獲取要綁定的函數(shù)
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP ? this : oThis || this,
//this指向函數(shù)的調(diào)用者芜茵,當(dāng)函數(shù)普通調(diào)用時,this指向 oThis || this
//作為構(gòu)造函數(shù)調(diào)用時 this指向構(gòu)造出來的新對象
//新對象的原型指向fNOP的實例
//fNOP的實例的原型又指向綁定函數(shù)的原型
//使用綁定后函數(shù)構(gòu)造出來的新對象的原型也指向綁定函數(shù)的原型
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;// 把fNOP的原型指向綁定的函數(shù)
fBound.prototype = new fNOP(); //把fBound的原型指向fNOP構(gòu)造出來的新對象
//fBound的原型被指定為new fNOP()倡蝙,
//也就是說如果我們綁定了一個構(gòu)造函數(shù)A得到新的構(gòu)造函數(shù)B九串,則使用B構(gòu)造的對象仍然會是A的實例,只不過原型鏈被new fNOP插了一腳
//反正new fNOP()本身是{}沒有什么屬性寺鸥,插這一腳不影響新對象的使用
return fBound;
};
}
// 簡單寫法
if(!Function.prototype.bind){
Function.prototype.bind = function (obj) {
var arr = Array.prototype.slice.call(arguments,1),
_self=this,
return function(){
_self.apply(obj,arr.concat(Array.prototype.silce.call(arguments)));
}
}
}