javascript 中各种继承方式的优缺点 (转)

javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现。下面对各种实现方式进行分析,总结各自的优缺点。

一 原型继承

let Super = functioin(name) {
    this.name = name;
    this.setName = (newName) => {
        this.name = name;
    };
    this.getName = () => {
        return this.name;
    }
}

let Sub = function(sex) {
    this.sex = sex;
}
Sub.prototype = new Super(‘eric‘);  //通过改变原型对象实现继承
let sub1 = new Sub(‘male‘)
     sub2 = new Sub(‘female‘);

sub1.setName(‘ada‘);
// 这里必须通过setName方法来修改继承来的name属性。
// 如果通过sub1.name== ‘ada‘,就打不到目的,因为此时sub1对象上没有name属性,
// 这样等于为该对象添加了新的属性,而不是修改继承而来的name属性。
console.log(sub2.name); // ada,可见此sub2的name也会被修改掉
console.log(sub1.getName === sub2.getName) // true,复用了方法
     

优点:父类的方法(getName)得到了复用。

缺点:同理父类的属性(name)也是复用,即子类实例没有自己的属性。

二 构造函数实现继承

let Super = function(name) {
    this.name = name;
    this.getName = () => {
        return this.name;
    }
}
let Sub = function(sex,name) {
    Super.call(this,name); // 调用父类方法为子类实例添加属性
    this.sex = sex;
}

let sub1 = new Sub(‘male‘,‘eric‘),
     sub2 = new Sub(‘female‘,‘eric‘);
sub1.name = ‘ada‘;
console.log(sub2.name); // eric,实例的属性没有相互影响

console.log(sub1.getName === sub2.getName); // false,可见方法没有复用

优点:子类的每个实例都有自己的属性(name),不会相互影响。

缺点:但是继承父类方法的时候就不需要这种特性,没有实现父类方法的复用。

三 组合式继承

let Super = function(name) {
    this.name = name;
}
Super.prototype = {
    constructor: Super, // 保持构造函数和原型对象的完整性
    getName() {
        return this.name;
    }
}
let Sub = function(sex) {
    Super.call(this,‘eric‘); //继承父类属性
    this.sex = sex;
}
Sub.prototype = new Super(‘eric‘); //继承父类方法
Sub.prototype.constructor = Sub;
let sub1 = new Sub(‘male‘),
    sub2 = new Sub(‘female‘);
// 可以按上述两种方法验证,复用了父类的方法,实例没有复用,达到目的

优点:继承了上述两种方式的优点,摒弃了缺点,复用了方法,子类又有各自的属性。

缺点:因为父类构造函数被执行了两次,子类的原型对象(Sub.prototype)中也有一份父类的实例属性,而且这些属性会被子类实例(sub1,sub2)的属性覆盖掉,也存在内存浪费。

四 寄生组合式继承

let Super = function(name) {
    this.name = name;
}
Super.prototype = {
    constructor: Super,
    getName() {
        return this.name;
    }
}
let Sub = function(sex,name) {
    Super.call(this,name);
    this.sex = sex;
}
// 组合继承的缺点就是在继承父类方法的时候调用了父类构造函数,从而造成内存浪费,
// 现在只要解决了这个问题就完美了。那在复用父类方法的时候,
// 使用Object.create方法也可以达到目的,没有调用父类构造函数,问题解决。
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;

五 es6中的class

class Super() {
    constructor(props = { name: ‘eric‘ }) {
        this.name = props.name;
    }
    setName(name) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}
class Sub extends Super {
    constructor(props) {
        super(props = { sex: ‘male‘ }); // 创建实例,继承父类属性和方法
        this.sex = props.sex;
    }
}
let sub1 = new Sub({
    name: ‘eric‘,
    sex: ‘male‘
})
let sub2 = new Sub({
    name: ‘eric‘,
    sex: ‘female‘
})
时间: 2024-10-06 05:26:14

javascript 中各种继承方式的优缺点 (转)的相关文章

javascript 中实现继承的六种方式

javascript 中对于继承的描述: 许多面向对象语言都支持两种继承的方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.在 javascript 中由于函数没有签名也就无法实现接口继承,而只支持实现继承,而且实现继承主要通过原型链来实现的. 先引述下官方文档对于原型链的描述:其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.要理解这个概念要先弄清楚构造函数,原型,和实例的关系:每个构造函数(只要是函数)都有一个 prototype 属性该属性指向一

javascript中实现继承的几种方式

javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Child1(){ Parent1.call(this); this.type = "child1"; } 缺点:Child1无法继承Parent1的原型对象,并没有真正的实现继承(部分继承) 2.借用原型链实现继承 function Parent2(){ this.name = "p

JavaScript学习13 JavaScript中的继承

JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式:对象冒充 function Parent(username) //父类对象 { this.username = username; //下面的代码最关键的部分就是将子对象的this传递给了父对象 this.sayHello = function() { alert(this.username); } } f

JavaScript中的继承机制

JavaScript到底是不是面向对象的?! 有人说是,有人说基于对象更准确,因为JavaScript没有类.不去管它,但JavaScript确实提供了一些面向对象的机制. 本文主要讨论JavaScript中的继承.继承,简单来说,就是让子类获得父类的属性和方法,以达到共享和复用的目的. 在开始继承之前,首先需要创建父类.为了后续讨论的需要,我分别为父类创建了私有对象.实例对象.引用对象和两个实例方法. 创建父类的代码如下: // 父类实例的构造函数 function Pet(name,soun

JS中对象继承方式

JS对象继承方式 摘自<JavaScript的对象继承方式,有几种写法>,作者:peakedness 链接:https://my.oschina.net/u/3970421/blog/2872629 方式一:对象冒充 原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使Parent构造函数称为Children的方法,然后调用它.Children会收到Parent的构造函数中定义的属性和方法. *** //父类构造函数 var P

JavaScript 的对象继承方式,有几种写法?

JavaScript 的对象继承方式,有几种写法? 一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Parent 构造函数 成为 Children 的方法,然后调用它.Children 就会收到 Parent 的构造函数中定义的属性和方法.例如,用下面的方式定义 Parent 和 Children: 原理:就是把 Parent 构造函数放到 Children 构造函数里面执行一次.那为什么不直接执行,

JavaScript中的继承(原型链)

一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.property = true; } SupType.prototype.getSupvalue = function() { return this.property; }; function SubType() { this.subproperty = false; } //原型对象等于一个类型的实例

JavaScript各种继承方式和优缺点

好久没写博客啦,嘻嘻,这个月是2017年的最后一个月啦,大家应该都开始忙着写年终总结了吧,嘻嘻,小颖今天给大家分享下Javascript中的几种继承方式以及他们的优缺点. 1.借助构造函数实现继承 原理:通过call()函数修改 this 指向,从而实现将父类属性挂载到子类实例中. function parent1() { this.name = 'parent1'; } function child1() { parent1.call(this); this.type = 'child1';

Javascript中实现继承的方式

js中实现继承和传统的面向对象语言中有所不同:传统的面向对象语言的继承由类来实现,而在js中,是通过构造原型来实现的,原型与如下几个术语有关: ①构造函数:在构造函数内部拥有一个prototype属性,这个属性指向原型.在js中,构造函数和函数是属于一个概念范畴,都是引用类型,都可以实例化为对象.唯一不同的地方是使用上的不同,用new关键字来调用函数就能让这个函数变成一个构造函数,这一点很好理解,因为在像java.C#这中类C语言中构造函数就是和方法是同名的.而如果要实例化一个类,那么就用new