建立一個小貓構造函數,代碼以下:瀏覽器
function Cat(name,color){ide this.name = name;函數 this.color = color;this
this.run=function(){spa alert(「一隻」+this.color +」的小貓飛奔過來...」);prototype }debug this.eat=function(){對象 alert(this.name +」要吃魚」);blog }繼承 }
var cat1 = new Cat(); |
以上全部用this定義方法,this表明新的實例,都會在建立新實例時爲其建立一個方法副本。
是否是有點多餘,怎麼解決 ??
分析:每個類型都擁有的特性,每次在實例級別定義確實有點浪費,那麼若是能在類級別定義,每個實例自動擁有類的通用特徵就行了。在這裏咱們就要用到prototype。
在JavaScript中,函數自己也是一個包含了「方法」和「屬性」的對象。好比以前學了一些方法(如constructor())及屬性(如name和length)等等。
如今來介紹一個新的屬性--原型Prototype。
咱們建立的每一個函數都有一個 prototype(原型)屬性,他指向一個對象,而這個對象的用途是包含能夠由特定類型的全部實例共享的屬性和方法。
// 定義一個構造器 function Person(name,age){ } // 函數的形參個數 console.debug(Person.length)// ==>2 // 構造函數 console.debug(Person.constructor)// ==> Function() // 原型類型 console.debug(typeof Person.prototype)// ==>object // 原型內容 console.debug(Person.prototype)// ↓↓
|
每個類(構造函數)都具備一個prototype屬性,當建立這個類的實例對象原型對象的全部屬性都被當即賦予要建立的對象中。
設值:
構造函數.原型.屬性=屬性值
構造函數.原型.方法=函數
取值:
對象.屬性
對象.方法()
原生屬性的優先級高於原型屬性。遵循從上到下查找:
訪問對象上面的屬性,直接經過object.name訪問。
神奇的user.__proto__屬性,該屬性其實就是對應User類的prototype屬性。
console.debug(user.__proto__===User.prototyp);//==> true;
_proto_屬性屬於對象實例,prototype屬性類的屬性。
每一個對象在建立後,都會自動創建一個到prototype上的引用,讓對象具有類型原型的全部特徵。
一個對象中的__proto__(prototype)屬性中的成員,能夠直接經過object.成員進行訪問。
總結:每一個類都有獨立的prototype屬性,向prototype對象上面添加屬性,對象實例能夠共享prototype對象上面的屬性,若是對象自己已存在某個屬性,使用對象自己上面的屬性,若是沒有則使用prototype上面的屬性,若是是添加屬性添加到對象上面,不影響對象的原型對象。
咱們都知道,Array對象裏沒有insert(插入)和remove(刪除)兩個方法,都是用一個splice方法完成插入、刪除等操做。
// 在指定位置插入操做 Array.prototype.insert=function(index, obj){ this.splice(index, 0, obj); }
// 在指定位置刪除內容 Array.prototype.remove=function(index){ this.splice(index, 1); } |
在新版瀏覽器中,全部的有DOM元素都繼承於HTMLElement構造器。經過訪問HTMLElement的原型,瀏覽器能夠爲咱們提供擴展任意HTML節點的能力。
HTMLElement.prototype.remove = function() { if(this.parentNode){ this.parentNode.removeChild(this); } } |