2016-03-03 53 views
-1

在以下代碼:呼叫/綁定/應聘VS原型

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(用戶)),或者如果我使用用戶。打招呼();

所以我的問題是,有沒有理由使用其中一種方法?我認爲我曾經在某個地方看過,如果是這樣的話,在原型上創建事物會受到阻礙,爲什麼呢?

更正:

我錯誤地寫了Object.prototype中..而不是指定的(對象創建).prototype ..

+3

這是不好的做法,特別是修改Object.prototype。 'user.sayHello = function(){}'或'function sayHello(obj){}'怎麼樣? – elclanrs

+1

通過在'Object.prototype'中添加'sayHi',幾乎所有東西都有'sayHi'方法。 – zero298

+1

您不應該觸摸Object.prototype。否則,所有對象都會繼承此方法。 'new Date()。sayHi()','window.sayHi()','/\d/.sayHi()' ... – dfsq

回答

2

你不想使用Object.prototype.sayHi = function(){}的原因是,一旦你做了,其原型鏈中的所有Object將能夠使用sayHi。這是原型繼承的核心。

將物品添加到創建的對象原型中(向Object.prototype添加它只是被認爲是不好的做法)。要明白,當你這樣做時,你的對象原型鏈中的任何東西都能夠使用該功能。

function sayHello() { 
    console.log("hello"); 
} 

// Bad 
Object.prototype.hello = sayHello; 
Date.hello(); // Prints hello 

呼叫,應用,綁定實際上是從添加到原型和綁定也從不同的電話及應用,以及略有不同。

呼叫和應用

Function.call()Function.apply()使用任何功能,您所呼叫或在通話或應用瞬間申請。

例如,如果我們想用呼叫之間的NodeList

var els = document.querySelectorAll("div"); 
Array.prototype.forEach.call(els, function(el){ 
    el.classList.add("someClass"); 

很大的區別的forEach()方法和應用是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周圍,並調用它,當你想它會有正確的範圍「綁定」。

0

這是非常不好的做法,修改Object.prototype中,因爲每一個對象從它繼承,所以現在創建的每個對象都會有一個名爲sayHi的方法,甚至沒有屬性名稱的對象。

如果你要創建自己的類說,這是可以接受的sayHi的方法添加到原型列表,因爲那麼只有類型的實例,將有方法:

function Person(name){ 
    this.name = name; 
} 

Person.prototype.sayHi = function() { return 'Hi ' + this.name; } 

至於選擇的一種方式或另一個,我會說這是最喜歡的。我傾向於使用原型來創建和使用這些原型在內部範圍內運行的對象。