ブラウザJSでも require('util').inherits 的なことができるとやっぱり都合がいいので、モジュール化してみた
inherits.js
(function (global) {
'use strict'
var isBrowser = !! global.self
var isWorker = !! global.WorkerLocation
var isNodeJS = !! global.global
function inherits (ctr, sCtr) {
var F = function () {}
F.prototype = sCtr.prototype
ctr.prototype = new F
ctr.prototype.constructor = ctr
ctr.super_ = sCtr
}
var utils = {
inherits: inherits
}
if (isNodeJS) {
module.exports = utils
}
else {
global.utils || (global.utils = {})
for (var method in utils) {
global.utils[method] = utils[method]
}
}
})(this.self || global)
単純な継承
- Person.prototypeオブジェクトを祖先に持つオブジェクト
- コンストラクタは 継承もとの Person コンストラクタをそのまま使う
01.js
function Person (name, sex) {
this.name = name
this.sex = sex
}
Person.prototype.sayMySex = function () {
return this.sex
}
function Male (name) {
Person.call(this, name, 'male')
}
utils.inherits(Male, Person)
window.onload = onLoad
funcion onLoad () {
var boy = new Male('taro')
console.log(boy.name) // "taro"
console.log(boy.sayMySex()) // "male"
}
継承元のコンストラクタとは別のものに委譲した継承
- Person.prototypeオブジェクトを祖先に持つオブジェクト
- コンストラクタは 継承関係のない Superman コンストラクタを利用する(委譲する)
02.js
// コンストラクタの委譲先になるコンストラクタ
function Superman (name) {
this.name = name
this.sex = 'superman'
}
Superman.prototype.fly = function () { return 'i can fly' }
function Mondo () {
Superman.call(this, '中村主水')
this.profession = '仕置人'
}
utils.inherits(Mondo, Person)
function onLoad () {
var mondo = new Mondo
console.log(mondo.name) // "中村主水"
console.log(mondo.sayMySex()) // "superman"
console.log(mondo.profession) // "仕置人"
try {
console.log(mondo.fly())
} catch (err) {
console.log(err.message) // "Object #<Mondo> has no method 'fly'
}
}