1.原型继承
- 优点:子可以继承父类的方法进行共用
- 缺点:父类的所有引用类型数据会被子类共享,更改一个子类的数据其他的也会受影响
function Person() {
(this.name = "zs"), (this.id = [1]);
this.do = function () {
console.log(this.name);
};
}
Person.prototype.get = function () {
console.log("aaa");
};
function man() {}
man.prototype = new Person();//原型链上添加构造函数(原型类基继承)
const man1 = new man();
//把更改man1的信息
man1.name = 'lisi'
man1.id.push(2)
//!!这里要注意如果写man1.id = [1,2] man2是不会变为[1,2]的
//因为`man1` 和 `man2` 都是通过 `new man()` 创建的实例,它们的 `prototype` 都指向 `Person` 的实例
//push实际上修改了man1原型链上的属性,由于man2共享一个原型对象,所以也会变
//直接复制相当于man1的id属性指向新的数组,man2还是指向原来的数组
console.log(man1.name);//zs
console.log(man1.id);//[1]
man1.do()//zs
man1.get()//aaa
console.log('------------');
//获取man2
const man2 = new man()
console.log(man2.name);//lisi
console.log(man2.id);//[1,2]
man2.do()
2.构造函数的继承
- 优点:父类引用类型的不会被子类所共享
- 缺点:只能继承父类的实例属性和方法,不能继承原型属性或方法 就改变一个地方
function Person() {
(this.name = "zs"), (this.id = [1]);
this.do = function () {
console.log(this.name);
};
}
Person.prototype.get = function () {
return 111
};
//改动的地方
//这里调用this指向构造函数
function man() {
Person.call(this)
}
///
const man1 = new man();
//把更改man1的信息
man1.name = 'lisi'
man1.id.push(2)
console.log(man1.name);//zs
console.log(man1.id);//[1]
man1.do()//zs
man1.get()//报错---
3.组合继承
- 优点:解决了构造函数继承中不能调用父类原型对象上的属性和方法的问题
- 缺点:由于
call了一次又new了一次导致一个函数会被调用两次造成了不必要的开销
function Person() {
(this.name = "zs"), (this.id = [1]);
this.do = function () {
console.log(this.name);
};
}
Person.prototype.get = function () {
return 111
};
//这里调用this
function man() {
//第一次调用---1
Person.call(this)
}
//第二次调用---2
man.prototype = new Person();
const man1 = new man();
4.寄生组合继承
- 最优解决方案
简单写法:
function man() {
Person.call(this)
}
//复制一份
const fn = function(){}
fn.prototype = Person.prototype;
const man1 = new fn();
或者写一个clone用来克隆一个对象
5.ES6 class
class Car{
constructor(color,size){
this.color = color
this.size = size
}
}
class newCar extends Car{
constructor(color,size){
super(color,size)
this.color = 'black'
}
}