JavaScript中继承的多种方式和优缺点
Posted 难凉热血,码梦为生!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript中继承的多种方式和优缺点相关的知识,希望对你有一定的参考价值。
// 原型链继承
/**
* 1. 原型链继承
* 缺点:
* 1. 在子类中不能向父类传参
* 2. 父类中所有引用类型的属性会被所有子类实例共享,也就说一个子类实例修改了父类中的某个引用类型的属性时,其他子类实例也会受到影响
*/
function Parent() {
this.name = "parent";
this.hobby = ["sing", "rap"];
}
function Child() {
this.type = "child";
}
Child.prototype = new Parent();
let child1 = new Child();
let child2 = new Child();
child1.hobby.push("basketball");
console.log(child1.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
console.log(child2.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
/**
* 2. 经典继承(借助call)
* 优点:
* 1. 可以向父类传参
* 2. 避免了父类中的引用类型属性在子类中共享的问题
* 缺点:
* 1. 父类原型对象上的方法子类继承不到
*/
function Parent(age) {
this.name = "parent";
this.age = age;
this.hobby = ["sing", "rap"];
}
Parent.prototype.sayHi = function() {
console.log("Hi");
};
function Child(age) {
Parent.call(this, age);
this.type = "child";
}
let child1 = new Child(15);
let child2 = new Child(15);
child1.hobby.push("basketball");
console.log(child1.name); // parent
console.log(child1.age); // 15
console.log(child1.type); // child
console.log(child1.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
console.log(child2.hobby); // [ ‘sing‘, ‘rap‘ ]
child1.sayHi(); // 报错,child1.sayHi is not a function
/**
* 3. 组合式继承
* 优点:
* 1. 可以向父类传参
* 2. 避免了父类中的引用类型属性在子类中共享的问题
* 3. 父类原型对象上的方法子类也可以继承到
* 缺点:
* 1. 父类实例化了两次,一次是在Child.prototype = new Parent()时,另一次是在子类构造函数中Parent.call(this,age)
*/
function Parent(age) {
this.name = "parent";
this.age = age;
this.hobby = ["sing", "rap"];
}
Parent.prototype.sayHi = function() {
console.log("Hi");
};
function Child(age) {
Parent.call(this, age);
this.type = "child";
}
Child.prototype = new Parent();
let child1 = new Child(15);
let child2 = new Child(15);
child1.hobby.push("basketball");
console.log(child1.name); // parent
console.log(child1.age); // 15
console.log(child1.type); // child
console.log(child1.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
console.log(child2.hobby); // [ ‘sing‘, ‘rap‘ ]
child1.sayHi(); // Hi
/**
* 4. 组合式继承优化1
* 优点:
* 1. 可以向父类传参
* 2. 避免了父类中的引用类型属性在子类中共享的问题
* 3. 父类原型对象上的方法子类也可以继承到
* 4. 父类也只执行了一次
* 缺点:
* 1. 子类实例的构造函数指向了父类,应该指向子类
* 2. 增加 Child.prototype.testProp = 1; 同时会影响 Parent.prototype 的
*/
function Parent(age) {
this.name = "parent";
this.age = age;
this.hobby = ["sing", "rap"];
}
Parent.prototype.sayHi = function() {
console.log("Hi");
};
function Child(age) {
Parent.call(this, age);
this.type = "child";
}
Child.prototype = Parent.prototype;
Child.prototype.testProp = 1
console.log(Parent.prototype);
let child1 = new Child(15);
let child2 = new Child(15);
child1.hobby.push("basketball");
console.log(child1.name); // parent
console.log(child1.age); // 15
console.log(child1.type); // child
console.log(child1.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
console.log(child2.hobby); // [ ‘sing‘, ‘rap‘ ]
child1.sayHi(); // Hi
console.log(child1.__proto__.constructor); // [Function: Parent]
/**
* 5. 组合式继承优化2
* 完美!!!
*/
function Parent(age) {
this.name = "parent";
this.age = age;
this.hobby = ["sing", "rap"];
}
Parent.prototype.sayHi = function() {
console.log("Hi");
};
function Child(age) {
Parent.call(this, age);
this.type = "child";
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
let child1 = new Child(15);
let child2 = new Child(15);
child1.hobby.push("basketball");
console.log(child1.name); // parent
console.log(child1.age); // 15
console.log(child1.type); // child
console.log(child1.hobby); // [ ‘sing‘, ‘rap‘, ‘basketball‘ ]
console.log(child2.hobby); // [ ‘sing‘, ‘rap‘ ]
child1.sayHi(); // Hi
console.log(child1.__proto__.constructor); // [Function: Child]
以上是关于JavaScript中继承的多种方式和优缺点的主要内容,如果未能解决你的问题,请参考以下文章