-1

據我所知,Prototypal inheritanceclosure是創建對象的兩種不兼容的方式。在javascript中,當Prototypal繼承比閉包更適合創建對象時?

  • 有了原型,所有實例共享相同的功能
  • 閉包,每個實例都有其自身的功能(其具體結束)

通過使用clojure創建對象,我指的是以下模式:

function createPerson(p){ 
      return { 
       getName: function() { return p;} 
      }; 
    } 

當編寫JavaScript應用程序,prototype比更好的選擇創建對象?我不在尋找關於prototypal inheritance的優點的一般性解釋。相反,我希望看到一個真實網頁開發情況,其中prototype inheritance真的很有用。

我能想到的唯一有用的例子是增加基本類型。

+1

誰告訴你原型繼承和關閉是兩個不兼容的範例? – KooiInc 2012-03-12 07:12:40

+0

原型繼承和關閉是完全不同的主題。沒有比較它們的問題。它們都是JavaScript的強大功能。 – Sarfraz 2012-03-12 07:14:51

+0

@Sarfraz我的問題是:什麼樣的問題,在JavaScript更好地解決原型? – viebel 2012-03-12 07:19:16

回答

1

在你的新例子中,你不「創造一個人」。相反,你返回一個普通的js對象。 再次,是不是縫合與protytpe,因爲我也可以有:

function createPerson(p){ 
     return { 
      name : p, 
      getName: function() { return this.name } 
     }; 
} 

這不採取封閉的優勢,但使用相同的方法來創建一個對象的實例。正如你看到的,再次使用closure無關對象的創建,可以使用 - 或不 - 在一起,儘管如果你使用原型或不:

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

Person.prototype.getName = function(name) { 
    return name; 
} 

我通常避免這種情況,但你可以擁有它。另外:

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

所以,如果你的問題是「我爲什麼要以這種方式創建的,而不是一個普通的對象的對象」 - 這無關與關閉 - 答案是「因爲你利用繼承「:如果你是在內存中創建數百萬個對象,他們都共同具有很多的方法相同的原型父

function Mutant(name) { 
    Person.call(this, name); 
} 

Mutant.prototype = Object.create(Person.prototype); 

var cyclops = new Mutant("Scott Summers"); 

alert(cyclops instanceof Person) // true 

alert(cyclops instanceof Mutant) // true 

alert(cyclops instanceof Object) // true 
+0

你說得對。我的問題是:爲什麼我應該用這種方式創建一個對象而不是一個普通的對象? – viebel 2012-03-14 13:57:40

+0

因爲繼承。因爲你有原型鏈,所以你可以繼承其他對象的屬性和方法。如果你不在乎擁有不同類型的對象,那麼你可以使用Object來獲得你需要的所有屬性和方法。實際上,你也可以利用繼承的優點,而不用直接使用構造函數的原型和函數,而只是使用'Object.create'的對象。 – ZER0 2012-03-14 14:02:49

3

在這個問題中提出的問題聽起來不正確。閉包和原型繼承是語言的兩個不同方面,它們不是不兼容的。 JS是基於原型而不是類的OOP語言。閉包是一種保持活動範圍超出其執行範圍的方法。我不明白他們爲什麼不相容。打一個比方,我能有這樣的事情:

function MyButton(tag) { 
    tag.addEventListener("click", this.onClick.bind(this), false); 
} 

MyButton.prototype = { 
    constructor: MyButton, 

    onClick : function(event){ 
     this.doSomething(); 
    }, 

    doSomething : function() { 
     // do something 
    } 
} 

function MySpecialButton(tag) { 
    MyButton.call(this, tag); 
} 

MySpecialButton.prototype = Object.create(MyButton); 

MySpecialButton.prototype.doSomething = function() { 
    // do something else 
} 

注意與bind我創建一個閉包,只是在一個更優雅的方式,在支持ES5。您可以使用一個更明確的封閉獲得相同的結果,如果你想:

function MyButton(tag) { 
    var myself = this; 
    tag.addEventListener("click", function(event) { myself.onClick(event) }, false); 
} 

您使用原型繼承有,好,繼承和封閉,讓你想要的範圍,當你需要它。

+0

感謝您的回答。實際上,我指的是用於創建對象的'closure'。我修改了這個問題,使之更加清晰。 – viebel 2012-03-12 07:51:59

1

原型繼承是有用的。這意味着他們可以共享同一個父級,因此在瀏覽器中佔用較少的內存。

+0

任何**真實生活**例子,當它發生在網頁開發? – viebel 2012-03-12 09:02:43

+0

請投票,以免問題關閉 – viebel 2012-03-12 09:03:03