2016-12-13 JavaScript 中几种不同的基于 prototype 继承方式的区别

JavaScript 中几种不同的基于 prototype 继承方式的区别

普通属性的继承

第一种方式

来自于 MDN 对象模型的细节

function Employee1 (name, dept) {
    console.log('Employee constructor')
    this.name = name || "";
    this.dept = dept || "general";
    this.work = function() {console.log("Employee.work")}
    this.workAsEmployee = function() { this.work() }
}

function WorkerBee1 (projs) {
    console.log('WorkerBee constructor')
    this.projects = projs || [];
    this.work = function() {console.log("WorkerBee.work")}
    this.workAsBee = function() { this.work() }
}
WorkerBee1.prototype = new Employee1;

function Engineer1 (mach) {
    console.log('Engineer constructor')
    this.dept = "engineering";
    this.machine = mach || "";
    this.work = function() {console.log("Engineer.work")}
    this.workAsEngineer = function() { this.work() }
}

Engineer1.prototype = new WorkerBee1;

e1 = new Engineer1()
e1.work()
console.log(Employee1.prototype.isPrototypeOf(e1))
console.log(WorkerBee1.prototype.isPrototypeOf(e1))
console.log(e1)

第二种方式

来自于 YUI 的实现,利用中间对象传递 prototype

可以看到,区别主要在于,直接 Child.prototype = new Parent() 会把定义在 Parent 里面的方法也带到 prototype 里面去。另外,这种方式并没有执行父类的构造函数。

对于定义在 prototype 里面的方法呢

下面对上面的方法定义进行一点改进,把方法定义在 prototype 里,类似正常的 OO 编程中在类里面定义方法。

第一种方式改进

第二种方式的改进

注意观察 constructor__proto__ 属性。

要执行所有构造函数

上述第二种方法,都没有执行父类的构造函数,也就没有真正的继承父类的初始化数据。为了弥补这一点,如下两种写法都可以达到目的。

利用 super 变量

类似,但是用 Parent.apply 方法

最后更新于

这有帮助吗?