[英]Call/Bind/Apply vs prototype
在下面的代碼中:
function User(name) {
this.name = name;
}
var user = new User('Jason Bourne');
User.prototype.sayHi = function() {
return 'Hi ' + this.name;
};
var sayHello = function() {
return 'Hello ' + this.name;
};
如果將對象綁定到sayHello(sayHello.bind(user))或使用user.sayHi(),則這兩個函數將給我相同的結果。
所以我的問題是,是否有理由使用一種方法而不是另一種方法? 我以為我讀過某個地方不鼓勵在原型上創建東西,如果可以,為什么?
更正:
我錯誤地編寫了Object.prototype ..而不是指定(我創建的對象).prototype ..
您不想使用Object.prototype.sayHi = function(){}
是,一旦這樣做,原型鏈中所有具有Object
都將能夠使用sayHi
。 這就是原型繼承的核心。
這是確定的事情添加到您創建(和它只是被認為是不好的做法添加到對象的原型Object.prototype
)。 只需了解一下,當您這樣做時,對象原型鏈中的任何內容都將能夠使用該功能。
function sayHello() {
console.log("hello");
}
// Bad
Object.prototype.hello = sayHello;
Date.hello(); // Prints hello
Call,Apply和Bind實際上與添加到原型稍有不同,Bind和Call and Apply也有所不同。
Function.call()
和Function.apply()
在調用或應用時使用您正在調用或應用的任何函數。
例如,如果我們想在NodeList
上使用forEach()
方法
var els = document.querySelectorAll("div");
Array.prototype.forEach.call(els, function(el){
el.classList.add("someClass");
call和apply之間的最大區別在於, call
采用可變參數,而apply
采用數組。
function say() {
console.log(arguments);
}
say.call(this, "a", "b");
say.apply(this, ["a", "b"]);
使用Function.bind()
實際上是另一回事。 綁定使您可以創建上下文綁定,在其中可以根據需要從特定上下文中調用函數。
function honk() {
console.log(this.sound);
}
function Car() {
this.sound = "honk";
}
function Van(){
this.sound = "beep";
}
var c = new Car();
var v = new Van();
var ftorCar = honk.bind(c);
var ftorVan = honk.bind(v);
ftorCar(); // prints honk
ftorVan(); // prints beep
現在,您可以傳遞ftorCar
並在需要時調用它,它將具有正確的作用域“綁定”。
修改Object.prototype是非常不好的做法,因為每個對象都繼承自它,因此,現在創建的每個對象都將具有一個名為sayHi的方法,即使沒有屬性名稱的對象也是如此。
如果要創建自己的類say,可以將sayHi方法添加到原型列表中,因為這樣只有該類型的實例才具有該方法:
function Person(name){
this.name = name;
}
Person.prototype.sayHi = function() { return 'Hi ' + this.name; }
至於選擇一種或另一種方式,我會說這是首選。 我傾向於將原型用於我創建的對象,並在內部范圍內使用這些原型運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.