聖杯模式的存在是用來繼承已有原型物件(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();
聖杯模式是透過已經存在的構造函數(Factory)建構一個實例物件(P),然後我們自訂一個建構子(C),讓這個建構子(C)的原型屬性指向這個實例物件(P)(臨時建構子的實例物件),這樣我們改變自訂的建構子(C)原型屬性是的屬性成員時候,其實改變的只不過是實例物件(P) 中的屬性成員
原型鏈存取的原則是:先在當前物件中遍歷是否存在該成員,若存在,則直接訪問,若不存在則訪問其原型物件…。原型鏈上沒遍歷到則回傳 undefined。
實例可以存取原型物件中的屬性成員,卻不可以實例.成員= value
去修改原型物件中的成員, 實例.成員相當於對目前的實例會新增一個屬性成員並賦值。
以上是js之聖杯模式講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!