js面向對象-原型模式

什麼是原型模式

使用構造函數的 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屬性->原型對象函數

  • Object.getPrototypeOf() ,在全部支持的實現中,這個

方法返回 [[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" ——
  • 使用 hasOwnProperty()方法能夠檢測一個屬性是存在於實例中,仍是存在於原型中。屬性存在於對象實例中時,纔會返回 true 。
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 操做符, 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"(沒有問題!)

原型對象的問題

  • 構造函數指向須要手工寫入
  • 對於引用類型來講有共享問題的錯誤
相關文章
相關標籤/搜索