持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
Node在源码中使用了大量的继承,在对源码的观察中我们来看一下实现继承的方式,官方推荐的node是使用extends来实现继承,但是从底层中依然是保留了原始的继承方法
1、源码实现
我们来看一下源码中的fs模块源码,fs模式是通过继承events模块实现的
function FSWatcher(){
EventEmitter.call(this)
}
Uint8ClampedArray.inherits(FSWatcher,EventEmitter)
官方推荐我们使用util.inherits方法来实现继承,我们再源码中来看看对应的实现,这里我们抛开源码中的错误处理,来简单的看一下实现方法,其实是通过setPrototypeOf来实现的继承
exports.inherits = function(ctor,superCtor){
ctor.super = superCtor
Object.setPrototypeOf(ctor.prorotype,superCtor.prorotype)
}
2、setPrototypeOf
用法
让我们来看一下setProtype的用法
Object.setPrototypeOf(a.prototype,b.prototype)
这个api是对obj设置原型,prototype是给obj新设置的原型,返回值是指定的对象
来一个小栗子,我们声明一个Car的类,然后通过prototype设置某些函数在上面,但我们在声明另外一个类,并且实用继承的方式结合俩个类,那么我们在bike类中,就可以看出,我们同个new 一个bike,并且执行run函数的时候是可以自执行的,并且输出的值是我们定义在car类上面的函数值
function Car(){
this.color = 'red'
this.name = 'car'
}
Car.prototype.run = function(){
console.log(this.name+' is run run run');
}
Car.prototype.getColor = function(){
console.log('color'+this.color);
}
function Bike(){
this.color = 'blue'
this.name = 'bike'
}
Bike.prototype.go = function (){
console.log(this.name+' is go go go');
}
Object.setPrototypeOf(Bike.prototype,Car.prototype)
let b1= new Bike()
// let c1 = new Car()
b1.run()//bike is run run run
Object.setPrototypeOf()在 ECMAScript 2015 规范中。它通常被认为是设置对象原型的正确方法,而不是更具争议性的Object.prototype.__proto__属性
我们可以来看一下官方对整个api源码的解释,对于出传入的参数,我们会判断是否传入的数量大于俩个,否则会进行报错,并且我们需要typeof来进行判断传入的参数的类型
Object.appendChain = function(oChain, oProto) {
if (arguments.length < 2) {
throw new TypeError('Object.appendChain - Not enough arguments');
}
if (typeof oProto !== 'object' && typeof oProto !== 'string') {
throw new TypeError('second argument to Object.appendChain must be an object or a string');
}
const oNewProto = oProto,
oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);
for (const o1st = this.getPrototypeOf(o2nd);
o1st !== Object.prototype && o1st !== Function.prototype;
o1st = this.getPrototypeOf(o2nd)
) {
o2nd = o1st;
}
if (oProto.constructor === String) {
oNewProto = Function.prototype;
oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
this.setPrototypeOf(oReturn, oLast);
}
this.setPrototypeOf(o2nd, oNewProto);
return oReturn;
}