首頁  >  文章  >  web前端  >  js之聖杯模式講解

js之聖杯模式講解

小云云
小云云原創
2018-03-27 17:04:263230瀏覽

聖杯模式的存在是用來繼承已有原型物件(A.prototype)中的成員(主要是公用方法),同時根據自己的需求修改原型物件(A.prototype)以自訂符合我們要求的構造函數B,這個修改對已有的實例(a1,a2,…)不會產生影響。

普通繼承來共享變數

var Person =  function () {};
Person.prototype.sayHello = function () {
    console.log('hello');
};// 假设 person 原型属性上有很多方法和变量我们需要拿来使用,比如: spell这个方法我们要拿来继续使用Person.prototype.spell = function () {
    console.log('i can spell!');
};var personA = new Person();var personB = new Person();var personC = new Person();var personD = new Person();var personE = new Person();var personF = new Person();var personG = new Person();var personH = new Person();
personA.sayHello();
personA.spell();
personB.sayHello();
personB.spell();// ...// 之前应项目需求 实例化了很多对象, 现在需要 实例化 n 个说中文的对象,同时要具备之前的 spell相同能力 Person.prototype.sayHello = function () {
    console.log('你好');
};var chinaPersonA = new Person();var chinaPersonB = new Person();var chinaPersonC = new Person();var chinaPersonD = new Person();var chinaPersonE = new Person();
chinaPersonA.sayHello();
chinaPersonA.spell();
chinaPersonB.sayHello();
chinaPersonB.spell();// ...// 之前的对象还能说英文 hello 吗? 显然不能了personA.sayHello(); // 你好personA.spell();
personB.sayHello(); // 你好personB.spell();// 显然我们对已存在的原型对象修改,对别人使用的的或者说以前构建的对象产生了影响

聖杯模式解決問題

var Person = function () {}
Person.prototype.sayHello = function () {
    console.log('hello');
};
Person.prototype.spell = function () {
    console.log('i can spell!');
};var personA = new Person();var personB = new Person();
personA.sayHello();
personA.spell();var grailMode = (function () {
    return function (Origin, Target) {
        var Temp = function () {};// 临时构造函数
        Temp.prototype = Origin.prototype;
        Target.prototype = new Temp();  // 这里不是明白,为什么要加个临时构造函数
        Target.prototype.constructor = Target; // 目标构造函数原型属性constructor指向 目标构造函数
        Target.prototype.ancestor = Origin; // target 的生父
    }
})();// 我们定制的构造函数var ChinaPerson = function () {}
grailMode(Person, ChinaPerson);

ChinaPerson.prototype.sayHello = function () {
    console.log('你好');
}var ChinaPersonA = new ChinaPerson();
ChinaPersonA.sayHello();
ChinaPersonA.spell();

personA.sayHello();
personA.spell();

Conclusion

  1. 聖杯模式是透過已經存在的構造函數(Factory)建構一個實例物件(P),然後我們自訂一個建構子(C),讓這個建構子(C)的原型屬性指向這個實例物件(P)(臨時建構子的實例物件),這樣我們改變自訂的建構子(C)原型屬性是的屬性成員時候,其實改變的只不過是實例物件(P) 中的屬性成員

  2. 原型鏈存取的原則是:先在當前物件中遍歷是否存在該成員,若存在,則直接訪問,若不存在則訪問其原型物件…。原型鏈上沒遍歷到則回傳 undefined。

  3. 實例可以存取原型物件中的屬性成員,卻不可以實例.成員= value去修改原型物件中的成員, 實例.成員相當於對目前的實例會新增一個屬性成員並賦值。

#

以上是js之聖杯模式講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn