使用構造函數的 prototype 屬性來指定那些應該共享的屬性和方法。組合使用構造
函數模式和原型模式時,使用構造函數定義實例屬性,而使用原型定義共享的屬性和方法。瀏覽器
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true
實例(指針)->構造函數constructor屬性->prototype屬性->原型對象函數
方法返回 [[Prototype]] 的值。this
alert(Object.getPrototypeOf(person1) == Person.prototype); //true alert(Object.getPrototypeOf(person1).name); //"Nicholas"
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg"——來自實例 alert(person2.name); //"Nicholas"——來自原型 delete person1.name; alert(person1.name); //"Nicholas" ——
function Person() { } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1.hasOwnProperty("name")); //false person1.name = "Greg"; alert(person1.name); //"Greg"——來自實例 alert(person1.hasOwnProperty("name")); //true alert(person2.name); //"Nicholas"——來自原型 alert(person2.hasOwnProperty("name")); //false delete person1.name; alert(person1.name); //"Nicholas"——來自原型 alert(person1.hasOwnProperty("name")); //false
使用 in 操做符, in 操做符會在經過對象可以訪問給定屬性時返回 true ,不管該屬性存在於實例中仍是原型中。prototype
結合使用in和hasPrototypeProperty()能夠肯定屬性究竟是存在對象中仍是原型中指針
function hasPrototypeProperty(object, name){ return !object.hasOwnProperty(name) && (name in object); }
爲減小沒必要要的輸入,也爲了從視覺上更好地封裝原型的功能,更常見的作法是用一個包含全部屬性和方法的對象字面量來重寫整個原型對象.code
function Person() { } Person.prototype = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { alert(this.name); } }; // 重設構造函數,只適用於 ECMAScript 5 兼容的瀏覽器 Object.defineProperty(Person.prototype, "constructor", { enumerable: false, value: Person });
因爲在原型中查找值的過程是一次搜索,所以咱們對原型對象所作的任何修改都可以當即從實例上反映出來——即便是先建立了實例後修改原型也照樣如此。(可是重寫整個原型是不行的,由於切斷了構造函數與最初原型的聯繫)對象
var friend = new Person(); Person.prototype.sayHi = function(){ alert("hi"); }; friend.sayHi(); //"hi"(沒有問題!)