在大多數面嚮對象語言中,對象老是由類中實例化而來,類和對象的關係就像模具跟模件同樣。Javascript中沒有類的概念,就算ES6中引入的class也不過是一種語法糖,本質上仍是利用原型實現。在原型編程語言中,類並非必需的,對象不必定須要由類實例化而來,而是經過克隆另一個對象來獲得。編程
原型模式是用來建立對象的一種模式。在以類爲中心的語言中,要建立一個對象首先要指定這個對象的類型,而後實例化一個對象。使用原型模式建立對象時沒必要關心對象的具體類型,而是找到一個對象,而後經過克隆來建立一個如出一轍的對象。因此在前者中若是要根據一個對象建立多個相同的對象,咱們須要先保存這個對象的全部屬性信息,而後將屬性信息設置到新建立的對象上,而在原型模式中咱們只須要使用克隆就能完成一樣的功能。設計模式
在某些玄幻小說中常常會出現某些修真大能,以分身的形式遊走世間。這個過程很適合原型模式的應用:瀏覽器
function Master(){ this.blood = 100; this.level = 6; } var noumenon = new Master(); noumenon.level = 9; var ektype = Object.create(noumenon); console.log(ektype);
ES5提供了原生的克隆方法:Object.create,不支持這個方法的瀏覽器可使用以下代碼:app
function clone(obj){ function F(){}; F.prototype = obj; return new F(); } var ektype = clone(noumenon);
經過以上代碼,咱們看到了如何經過原型模式來克隆出一個如出一轍的的對象。原型模式的真正意義並不是建立一個如出一轍的對象,而是提供一種建立對象的方式,Javascript的面向對象機制是基於原型模式的,他的對象系統就是使用原型模式,經過克隆來建立的,克隆是建立一個對象的過程和手段。以繼承爲例:編程語言
function Person(name){ this.name = name; } function Developer(lang){ this.language = lang; } var p = new Person('coder'); Developer.prototype = p; var dev = new Developer('Javascript');
基於原型的繼承體系,子類的每次實例化都是對其構造函數的prototype屬性的克隆。因此每次建立Developer對象,其實都是在對p對象的克隆。函數
在Java等以類爲中心的面嚮對象語言中,常常使用new實例化一個對象。可是Javascript是基於原型的面嚮對象語言,在這裏new運算符建立對象的方式與Java中的new運算符並不相同,Javascript中的new運算符也是經過克隆來實例化對象的,克隆的是構造器函數的原型對象,new運算符的做用等同於以下代碼:this
function Person(name){ this.name = name; } function Developer(lang){ this.language = lang; } var p = new Person('coder'); Developer.prototype = p; function _new(_Constructor) { var that = Object.create(_Constructor.prototype); var args = Array.prototype.slice.call(arguments, 1); var other = _Constructor.apply(that, args); return (typeof other === 'object' && other) ? other : that; } _new(Developer, 'JavaScript')
從這咱們也能夠看出,Javascript的原型實際上存在着諸多矛盾,它的某些複雜語法看起來就像那些基於類的語言,這掩蓋了它的原型機制。因此jQuery中儘可能避免使用new運算符來建立對象。spa
根據前面所說Javascript中新建立的對象都是基於原有對象的克隆,因此在Javascript中存在一個最原始的對象:Object.prototype,全部對象都是由它克隆而來。prototype
這裏所說的克隆是在Javascript原型模式這一大環境下的一種語義表達,在計算機的物理世界中並不存在真正的克隆。因此這裏對於克隆應當理解爲產生一個擁有__proto__屬性指向原對象的對象的過程,原對象成爲被克隆的對象,也就是構造函數的prototype對象。設計
擁有以上共識後,咱們能夠獲得在Javascript中原型編程的基本規則:
參考書籍:
《Javascript語言精粹》
《Javascript設計模式與開發實踐》