JavaScript对象的继承
发表于 2021-11-16 | 更新于 2021-11-16
总字数: 1.1k | 阅读时长: 4分钟 | 阅读量:
JavaScript 对象的继承
原型链继承
基于原型链,即把一个对象的原型设置为另一个对象的实例,那么这个对象实例也就拥有了另一个对象上的属性。
function Father(){ this.nationality = "中国🇨🇳" } Father.prototype.getNational = function(){ console.log('中国🇨🇳') }
function Son(){ }
Son.prototype = new Father()
var s = new Son()
s.getNational() _ _```_ 原型和实例的关系 ```JavaScript s instanceof Son _ s instanceof Father _ _```_ 子类也可以继续添加其他的方法,但是需要注意,子类添加方法的代码要写在替换原型的代码之后 ```JavaScript function Father(){ this.nationality = "中国🇨🇳" } Father.prototype.getNational = function(){ console.log('中国🇨🇳') }
function Son(){ }
Son.prototype = new Father()
_ Son.prototype.learn = function(){ console.log('好好学习天天向上') }
|
借用构造函数
使用父类的实例设置为子类的原型,也就意味着父类的属性变成了子类原型上共享的属性了。我们在之前将面向对象时,说过,对象的属性最好定义在构造函数中,需要共享的引用类型的属性再定义在原型上。为了解决这个问题,我们可以在子类的构造函数中调用父类的构造函数,这样父类的属性就会变成子类构造函数上的属性,子类的实例对象也就有了独立的属性:
function Father() { this.nationality = "中国🇨🇳" }
function Son() { _ Father.call(this) } 传递参数: function Father(name) { this.name = name; this.nationality = "中国🇨🇳" }
function Son(name) { Father.call(this,name) }
|
组合继承模式
结合原型链和构造函数,原型链实现对原型属性和方法的基础,构造函数实现实例方法的继承:
function Father(name) { this.name = name; this.nationality = "中国🇨🇳" }
Father.prototype.getNational = function () { console.log('中国🇨🇳') }
function Son(name) { _ Father.call(this,name) }
Son.prototype = new Father()
Son.prototype.constructor = Son;
|
这种方法也是推荐的实现继承的方式
寄生式继承
function createPerson(origin) { var clone = Object(origin) clone.sayHello = function () { console.log('hello') } return clone; }
var person = { name: "davie", age: 20 }
var p2 = createPerson(person) p2.sayHello()
|
createPerson 方法返回了一个新的对象,具有 person 的属性,而且还有自己的方法。
当继承的父对象不是自定义类型和构造函数的情况下,可以采用寄生继承模式。
寄生组合式继承
组合继承模式是最常用的模式,但也不是完美的。组合继承会执行两次父类构造函数。一次是在子类构造函数中,一次在创建子类原型的时候。结合寄生模式,可以进一步优化:
function _inherit(subClass,supClass){ var prototype = Object(supClass.prototype) prototype.constructor = subClass subClass.prototype = prototype }
function Father(name){ this.name = name; } Father.prototype.sayHi = function(){ console.log(this.name) }
function Son(name,age){ Father.call(this.name) this.age = age; }
_inherit(Son,Father)
|
这种方法的高效之处体现在只调用了一次父类构造函数。因此避免了在子类的原型上添加不必要的、多余的属性。同时原型链还能保持不变,因此可以正常使用 instanceof 判断类型。
ES6 中类的继承
在 ES6 中,有了 class(JavaScript 的 class 只是一种语法糖,覆盖在基于构造函数和原型的模式上),我们就可以使用 extends 来实现类的继承了:
class Father { constructor(name) { this.name = name }
sayHi() { console.log(this.name) } }
class Son extends Father { constructor(name) { super(name) }
learn() { console.log('好好学习天天向上') } }
var s = new Son("Davie") s.sayHi() s.sayHi()
|
子类的构造函数可以不写。但是如果要写的话,一定要记得执行 super 函数。super 函数用来调用父类的构造函数。否则会报错:

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 aloeJun | Lu's Blog