Skip to content

Instantly share code, notes, and snippets.

@allenfantasy
Forked from hayeah/gist:9757971
Last active June 2, 2016 15:42
Show Gist options
  • Save allenfantasy/1e666aedf134938d7802 to your computer and use it in GitHub Desktop.
Save allenfantasy/1e666aedf134938d7802 to your computer and use it in GitHub Desktop.
Implementation of inheritance in CoffeeScript
var __hasProp = {}.hasOwnProperty;
var __extends = function(child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
// why set the prototype's constructor to child?
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
@allenfantasy
Copy link
Author

回答自己之前提出来的问题:child 和 parent 都是构造函数,但函数本身也可能带有属性(类似于基于类的OOP语言中的class variable ),所以需要复制给子构造函数。

避免子构造函数通过 prototype 污染 Parent 对象的方法的关键在于 ctor 。请看例子:

function Person() {
    this.age = 1;
    this.name = "foo";
}
Person.prototype.greet = function() {
    console.log("hello");
}
__extends(Student, Person);

function Student() {
    return Student.__super__.constructor.apply(this, arguments);
}
Student.prototype.greet = function() {
    console.log("hello, i am a student");
}

这段代码在最后尝试对 Student.prototype 进行修改,也就是我们所理解的重定义(override)。如果在 __extends 函数中不使用 ctor 作为过渡:

var __extends = function(child, parent) {
   // 省略前面复制属性的代码...
   child.prototype = parent.prototype; // 原来这里是用 ctor 的,现在不用了
   child.__super__ = parent.prototype;
   return child;
}

则会出现以下情况:

var p = new Person();
var s = new Student();

p.greet();  //=> hello, i am a student
s.greet();  //=> hello, i am a student

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment