2020-12-18

js的继承方式(共6种):
定义一个父级函数:
function Animal(name){
this.name = name;
this.sleep = function(){
console.log(this.name+“在睡觉”)
}
}
Animal.prototype.eat = function(food){
console.log(this.name+“再吃”+food);
}
  第一种:原型链继承(父类实例作为子类的原型)
function Cat(name){
this.name = name;
}
Cat.prototype.color = “白色”;
Cat.prototype = new Animal();
var cat1 = new Cat(“Tom”); // 实例1
var cat2 = new Cat(“Jim”); // 实例2
var cat3 = new Cat(“Sun”); // 实例3
console.log(cat1.name);
console.log(cat1.color); // undefined
console.log(cat2.sleep());
console.log(cat3.eat(“fish”))

特点:
简单易实现
父类实例的属性和方法子类都可以继承
缺点:
想要新增原型属性和方法必须放在new Animal()语句之后
不能实现多继承(一个子类同时继承多个父类)
来自原型对象的属性是所有实例共享的
创建子类实例时,无法向父类构造函数传参

第二种:构造函数继承(通过使用call改变this指向,指向父类实例,相当于复制父类实例的属性给子类)
function Cat(name){
Animal.call(this);
this.name = name;
}
var cat1 = new Cat(“Tom”);
console.log(cat1.name);
console.log(cat1.sleep());
console.log(cat1.eat(“fish”)) // cat1.eat is not a function

特点:
可以实现多继承
创建子类实例时可以向父类传参
缺点:
只能继承父类实例的属性和方法,不能继承原型的方法
函数不可复用
实例只是子类实例不是父类实例

第三种:实例继承(为父类实例添加新属性,作为子类实例返回)

复制代码
function Cat(name){
console.log(this)
var instance = new Animal();
instance.name = name;
return instance;
}
var cat1 = new Cat(“Tom”);
var cat2 = Cat(“Jim”);
console.log(cat1.name) // Tom
console.log(cat2.name) // Jim

特点:
不限制调用方式,new 构造函数 或者直接调用子类函数 得到的都是同样的结果
缺点:
不支持多继承
实例是父类实例,不是子类的实例
复制代码
第四种:拷贝继承(获取父类实例,通过循环父类实例,把父类实例的属性和方法都赋给子类)
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name;
}
var cat1 = new Cat(“Jim”);
var cat2 = new Cat(“Jim”);
console.log(cat1.name);
console.log(cat2.eat(“fish”));

特点:
可以实现多继承
缺点:
因为每次都要循环,造成内存消耗严重,效率低
不可以枚举的属性方法就会获取不到
  第五种:组合继承(通过调用父类的构造函数,继承了父类的属性和方法,并保留了传参的优点,通过将父类实例作为子类的原型,实现了函数的复用)
function Cat(name){
Animal.call(this);
this.name = name;
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// console.log(Cat.prototype.constructor);
var cat1 = new Cat(“Tom”);
var cat2 = new Cat(“Li”);
console.log(cat1.name);
console.log(cat2.eat(“apple”))
特点:
既可以继承实例的属性和方法,也可以继承构造函数的属性和方法
子类实例可以给父类传参
实例既是子类实例也是父类实例
函数可复用
缺点:
调用了两次父类构造函数,生成了两份实例
(1). 设置子类实例原型的时候 Cat.prototype = new Animal();
(2). 创建子类实例的时候 var cat1 = new Cat(“Tom”);
  第六种:寄生组合继承
function Cat(name){
Animal.call(this);
this.name = name;
}
(function(){
// 创建一个没有实例方法的类
var Cate = function(){

    }

// 将父类原型当做这个类的原型
Cate.prototype = Animal.prototype;
// 把实例作为子类的原型
Cat.prototype = new Cate();
})()
var cat1 = new Cat(“Tom”);
var cat2 = new Cat(“Jim”);
console.log(cat1);
console.log(cat2.eat(“apple”));
特点:
既可以继承实例的属性和方法,也可以继承构造函数的属性和方法
子类实例可以给父类传参
实例既是子类实例也是父类实例
可以实现多继承
函数可复用
通过寄生的方式,去掉了父类的实例属性,调用两次父类构造函数时不会初始化两属性和方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值