Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript实现继承的多种方式及优缺点(6种) #8

Open
GGXXMM opened this issue Aug 4, 2019 · 0 comments
Open

JavaScript实现继承的多种方式及优缺点(6种) #8

GGXXMM opened this issue Aug 4, 2019 · 0 comments
Labels
⭐️ js js knowledge

Comments

@GGXXMM
Copy link
Owner

GGXXMM commented Aug 4, 2019

1、原型链继承

function Parent () {
    this.name = 'zhangsan';
}
Parent.prototype.getName = function () {
    console.log(this.name);
}

function Child () {

}

Child.prototype = new Parent();
var child1 = new Child();

console.log(child1.getName()) //'zhangsan'

缺点:引用类型和所有实例共享原型链,如果父类引用类型的对象属性方法被修改,子类的原型属性和方法也会相应更改。

2、构造函数继承-借用call(经典继承)

function Parent() {
	this.colors = ["red", "blue", "green"];
}

function Child() {
	//继承Parent
	Parent.call(this);
}

var instance1 = new Child();
instance1.colors.push("black");
console.log(instance1.colors); //"red,blue,green,black"

var instance2 = new Child();
console.log(instance2.colors); //"red,blue,green"

优点:
1)避免了引用类型的属性被所有实例(子类)共享
2)子类可以向父类传参
缺点:
方法必须都在构造函数中定义。子类不能访问父类原型上的方法。

3、组合继承(原型链和构造函数组合继承)

function Parent(name) {
	this.name = name;
	this.colors = ["red", "blue", "green"];
}
Parent.prototype.sayName = function() {
	alert(this.name);
}
function Child(name, age) {
	// 继承属性
	Parent.call(this, name);
	this.age = age;
}
// 继承方法
Child.prototype = new Parent();
Child.prototype.sayAge = function() {
	alert(this.age);
};

var instance1 = new Child("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29

优点:融合原型链继承和构造函数继承的优点,该共享的共享,该私有的私有,是JavaScript中最常用的继承方式。

4、原型式继承

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}

就是 ES5 Object.create 的模拟实现,将传入的对象作为创建的对象的原型。
缺点:包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。

5、寄生式继承

创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象。

function createObj (o) {
    var clone = Object.create(o);
    clone.sayName = function () {
        console.log('hi');
    }
    return clone;
}

缺点:跟借用构造函数模式一样,每次创建对象都会创建一遍方法。

6、寄生组合式继承

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}	

function prototype(child, parent) {
	var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}
function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

prototype(Child, Parent);// 实现继承,相当于Child.prototype = new Parent()

var child1 = new Child('zhangsan', 18);
alert(child1.getName());// 'zhangsan'

优点:这种方式的高效率体现它只调用了一次 Parent 构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变。寄生组合式继承是实现继承最理想的方式。

@GGXXMM GGXXMM added the ⭐️ js js knowledge label Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⭐️ js js knowledge
Projects
None yet
Development

No branches or pull requests

1 participant