今天看到一篇文章,講到了JS中的繼承,提及了一個新的概念,聖盃模式。於是查閱了一下資料,看到對於聖盃模式的描述如下:
var inherit = ((Origin, Target)=>{
let F= function(){};
return (origin, target)=>{
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.ancestor = Origin.prototype;
}
})();
其對應解決的現實問題時,子類需要繼承父類的屬性和方法,並且需要根據自身的需求對父類中的方法進行相應的修改,但是修改後不能影響先前父類實例化之後實例方法。
其實個人感覺上面的方法是多餘的,既然想繼承父類的方法和屬性,又想自定義某些方法,同時不影響父類原型對象上的方法,根據JS的特性,使用原型委託是最好不過的。舉個列子。
function Person(){}
Person.prototype.hello = ()=>{console.log('hello')};
Person.prototype.spell = ()=>{console.log('spell')};
person1 = new Person();
function ChinaPerson(){}
現在想定義一個ChinaPerson
類,繼承自Person
,但是ChinaPerson
需要改寫hello
方法
最簡單的寫法如下:
ChinaPerson.prototype = Object.create(Person.prototype);
ChinaPerson.prototype.hello = ()=>{console.log('你好')}
person2 = new ChinaPerson();
person1.hello();
person1.spell();
person2.hello();
person2.spell();
這裏有一個簡化的版本:
function inherit(Origin, Target){
Target.prototype = Object.create(Origin.prototype);
Target.prototype.constructor = Target;
Target.prototype.ancestor = Origin.prototype;
}
上面的實例中,ChinaPerson
的hello
方法不會影響Person
中的hello
方法,兩者互不影響。而使用該方法和上面的聖盃模式,其本質都是一樣的,都是利用的原型鏈中的一個特性,默認情況下,修改對象的屬性時, 只會修改實例對象本身的屬性,如果不存在,則進行添加該屬性,不會去修改原型鏈上的屬性。