Skip to content

Instantly share code, notes, and snippets.

@ldong
Forked from CatTail/proto.js
Created June 1, 2017 21:09
Show Gist options
  • Save ldong/e4058e16e704848fa3f05627d847cd13 to your computer and use it in GitHub Desktop.
Save ldong/e4058e16e704848fa3f05627d847cd13 to your computer and use it in GitHub Desktop.
Javascript prototype in a nutshell
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment