js学习中的总结——几种继承模式
程序员文章站
2022-06-15 12:19:42
...
js中构造函数的几种继承模式浅析
一、原型链模式继承
利用原型让一个引用类型继承另一个引用类型的属性和方法 。
用的最多。
缺点:不可传参,不可多继承。
function People(name, age) {//添加公有属性
name = name || 'xiaolan';
age = age || 18;
this.name = name;
this.age = age;
}//创建一个名为People的类
People.prototype.eat = function() {//添加私有属性
console.log(this.name + '贼能吃');
}
function Cat(color) {//创建一个名为Cat的类
this.color = color;
}
Cat.prototype = new People('小叮当', 200);//实例化一个People类,并赋值给Cat类的原型链
var cat = new Cat('蓝白色')
console.log(cat.name)//'小叮当'
cat.eat();//'小叮当贼能吃'
二、混合模式继承
用call的方法只能继承私有属性,所以再加一遍一遍原型链模式继承,原型链模式继承又把私有属性和公有属性都继承了一遍。
function People(name, age) { //创建一个父级People类
name = name || 'xiaolan';
age = age || 18;
this.name = name;
this.age = age;
}
People.prototype.eat = function() {
console.log(this.name + '贼能吃');
}
function Cat(color, name, age) {
this.color = color;
People.call(this, name, age); //通过call的形式继承
//通过call(this),将People的指向改为Cat的实例
}
var cat = new Cat('蓝白色', '小叮当', 1);
console.log(cat.name);//'小叮当'
cat.eat();//报错,
//继承不了公有属性,所以cat.eat()会报错;
为了继承公有属性,用原型链模式在把公有属性和方法继承过来,
function People(name, age) { //创建一个父级People类
name = name || 'xiaolan';
age = age || 18;
this.name = name;
this.age = age;
}
People.prototype.eat = function() {
console.log(this.name + '贼能吃');
}
function Cat(color, name, age) {
this.color = color;
People.call(this, name, age); //通过call的形式继承
//通过call(this),将People的指向改为Cat的实例
}
Cat.prototype = new People()
var cat = new Cat('蓝白色', '小叮当', 200)
console.log(cat)
console.log(cat.name); //'小叮当',在原型链继承的时候,就近原则,cat.name 先找到'小叮当',就不往下找了
cat.eat(); //'小叮当贼能吃'
三、拷贝继承
优点:可以多继承,可传参;
缺点:浪费资源,不能判断父级;
function People(name, age) { //创建一个父级People类
name = name || 'xiaolan';
age = age || 18;
this.name = name;
this.age = age;
}
People.prototype.eat = function() {
console.log(this.name + '贼能吃');
}
function Cat(color, name, age) {
this.color = color;
var people = new People(name, age) //实例化一个People类
for (let i in people) {
this[i] = people[i]; //将people中的可枚举属性和方法遍历并附给Cat类,公有属性和私有属性都是可枚举属性;
}
}
var cat = new Cat('蓝白色', '小叮当', 2);
console.log(cat.name); //小叮当
cat.eat(); //小叮当贼能吃
四、寄生组合方式继承
优点:私有属性和公有属性都单独继承,可以传参;
私有属性可以多继承,公有属性不可多继承;
function People(name, age) {
name = name || 'xiaolan';
age = age || 18;
this.name = name;
this.age = age;
}
People.prototype.eat = function() {
console.log(this.name + '贼能吃');
}
function Cat(color, name, age) {
this.color = color;
People.call(this, name, age) //用call的形式把私有属性继承过来
}
function Fn() {} //创建一个中间构造函数,用来接收People的公有属性,为了防止创建实例Cat实例是影响原来的people构造函数
Fn.prototype = People.prototype;
Cat.prototype = new Fn(); //将中间构造函数Fn继承people的公有属性传给Cat的原型链
Cat.prototype.constructor = Cat; //由于上一步重置了Cat原型链的constructor属性,所以要重新给赋回来;
var cat = new Cat('蓝白色', '小叮当', 3);
console.log(cat.name); //'小叮当'
cat.eat() //'小叮当贼能吃
注:若有不严谨与错误的地方,请多指教!