今天看到一篇文章,讲到了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
方法,两者互不影响。而使用该方法和上面的圣杯模式,其本质都是一样的,都是利用的原型链中的一个特性,默认情况下,修改对象的属性时, 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,不会去修改原型链上的属性。