原型继承
function Parent(name) { this.name = name } Parent.prototype.getName = function(){ return 'parentPrototype' + ' ' + this.name; } function Son() { } Son.prototype = new Parent(); console.log(new Son())
内存图
分析
原型继承的原理就是把子类的prototype指向父类的实例身上,这样做,子类就可以使用父类的属性和方法了,但是,无法初始化父类的属性,这个时候,盗用构造函数继承就出现了
盗用构造函数继承
function Parent(name) { this.name = name } Parent.prototype.getName = function(){ return 'parentPrototype' + ' ' + this.name; } function Son(name) { Parent.call(this, name) } console.log(new Son('jack'))
分析
盗用构造函数的原理简单理解就是吧父类函数的代码 copy
到子类里面,在上述代码中相当于把父类的this.name = name
在子类里执行了一次,这样的话,就可以在子类实例化的时候初始化父类的一些属性
如果这样的话就取不到父类原型身上的方法了,为了解决这个问题,组合继承就出现了
组合继承
function Parent(name) { this.name = name } Parent.prototype.getName = function(){ return 'parentPrototype' + ' ' + this.name; } function Son(name) { Parent.call(this, name) // 第二次调用 } Son.prototype = new Parent() // 第一次调用 console.log(new Son('jack'))
组合继承,也称为伪经典继承,结合了原型继承和盗用构造函数继承,既可以初始化父类的方法,又可以取到父类的原型身上的方法
可以看到这种继承方式name会被多次创建,虽然在使用上没什么区别,但是会多开辟一些无用内存,而且还会多调用一次函数
原型链继承
const parent = { name: 'jack', getName() { return this.name } } const son = Object.create(parent) console.log(son)
这种继承适用于想在一个对象的基础上添加一个新的对象,这个新的对象可以有自己独立的属性
还可以有自己的属性:
const parent = { name: 'jack', getName() { return this.name } } const son = Object.create(parent, { age: { value: 18, enumerable: true, writable: true, configurable: true } }) console.log(son)
寄生式继承
const parent = { name: 'jack', getName() { return this.name } } function createObj(origin){ const res = Object(origin); res.age = 18; res.getAge = function() { return this.age }; return res } const son = createObj(parent) console.log(son)
寄生式继承就是类似于工厂模式,经过它创建的函数,会有一些自带的值
寄生组合式继承
function Parent(name) { this.name = name; } Parent.prototype.getName = function () { return this.name; } function Son(name) { Parent.call(this, name) }; function inhertPrototype(Son, Parent) { const res = Object(Parent.prototype); // 创建目标对象的原型对象 // 可以理解为复制父类对象prototype的属性,这样做可以少调用一次父类的实例化操作 res.constructor = Son // 将构造函数指向son Son.prototype = res //将子类的prototype 指向父类创建的原型对象,这样子类既可以使用父类的方法,又不用实例化父类 } inhertPrototype(Son, Parent) console.log(new Son('jack'))
寄生组合式继承 被称为最佳继承模式 他解决了组合继承父类函数被调用两次的问题,同时又不会给子类的prototype
加上父类的无用的属性
可以对比组合继承的图看一下,prototype
上少了 name
,最佳的继承方式
到此这篇关于JavaScript中常见的几种继承方式的文章就介绍到这了,更多相关js继承方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!