JavaScript 100 行代码理解 Javascript 原型

CatTail · 2017年05月19日 · 最后由 googya 回复于 2017年05月20日 · 6728 次阅读

gist 地址

写这段代码的初衷是在面试过程中没能很好回答原型的相关问题,因为平时工作很少用到,入门时学的内容也基本忘了,现在记录一下,方便自己和其他同学。

var assert = require('assert')
var util = require('util')

function test (inherits) {
    function Fruit () {

    }
    Fruit.prototype.round = false
    Fruit.prototype.sweet = true
    Fruit.prototype.eat = function () {}

    function Apple () {

    }
    inherits(Apple, Fruit)
    Apple.prototype.round = true

    var fruit = new Fruit()
    var apple = new Apple()

    // *class*, *instance* and *prototype*
    assert.equal(fruit.constructor, Fruit)
    assert.equal(fruit.constructor.prototype, Fruit.prototype)
    assert.equal(fruit.constructor.prototype.constructor, Fruit)
    assert.equal(Object.getPrototypeOf(fruit), Fruit.prototype)

    // *prototype chain*
    assert.equal(Object.getPrototypeOf(apple), Apple.prototype)
    assert.equal(Object.getPrototypeOf(Object.getPrototypeOf(apple)), Fruit.prototype)
    assert.equal(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(apple))), Object.prototype)
    assert.equal(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(apple)))), null)

    // *property*
    assert.equal(fruit.round, false)
    assert.equal(fruit.sweet, true)
    assert.equal(apple.round, true)
    assert.equal(apple.sweet, true)
    Apple.prototype = {}
    assert.equal(apple.round, true)
    assert.equal(apple.sweet, true)
    // magic *__proto__* property
    assert.equal(Object.getPrototypeOf(fruit), fruit.__proto__)
    apple.__proto__ = {}
    assert.equal(apple.round, undefined)
    assert.equal(apple.sweet, undefined)
}

var inherits0 = util.inherits
function inherits1 (constructor, superConstructor) {
    // leverage *new* keyword to setup prototype
    var EmptyFunc = function () {}
    EmptyFunc.prototype = superConstructor.prototype
    var proto = new EmptyFunc()
    proto.constructor = constructor
    constructor.prototype = proto
}
function inherits2 (constructor, superConstructor) {
    var proto = Object.create(superConstructor.prototype)
    proto.constructor = constructor
    constructor.prototype = proto
}
function inherits3 (constructor, superConstructor) {
    var proto = {}
    Object.setPrototypeOf(proto, superConstructor.prototype)
    proto.constructor = constructor
    constructor.prototype = proto
}
function inherits4 (constructor, superConstructor) {
    var proto = {}
    proto.__proto__ = superConstructor.prototype
    proto.constructor = constructor
    constructor.prototype = proto
}
test(inherits0)
test(inherits1)
test(inherits2)
test(inherits3)
test(inherits4)

要理解原型,看看这个图就好了:

正所谓,一图抵百语

需要 登录 后方可回复, 如果你还没有账号请 注册新账号