Skip to content

Instantly share code, notes, and snippets.

@tasogare3710
Created May 9, 2017 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tasogare3710/20ec55b5e1be2122c611591994e4d023 to your computer and use it in GitHub Desktop.
Save tasogare3710/20ec55b5e1be2122c611591994e4d023 to your computer and use it in GitHub Desktop.
ClassDeclarationを使わずにArrayのsubtypeを作る。
function A(...args) {
// 厳密に書くと...
//
// const value = Reflect.construct(Array, args, A)
// if(new.target !== undefined) {
// this = value
// } else {
// return value;
// }
//
// となるが、es5からthisへの代入が禁止されたため、returnするしかなくなり、
// 分岐が無駄になるので最適化する。
return Reflect.construct(Array, args, A)
}
Reflect.defineProperty(A, Symbol.species, { get: function(){ return this } })
A.prototype = {
__proto__: [],
constructor: A,
pop: function(){
console.log("loging: pop")
return Array.prototype.pop.call(this)
},
push: function(...args){
console.log("loging: push")
return Array.prototype.push.call(this, ...args)
},
}
// - - -
function assert(expr, thrower=function(e){ throw new TypeError(`assertion: unexpected ${e}`) }) {
if(expr === false){
thrower(expr)
}
}
function assertSome(a, b, thrower=function(x, y){ throw new TypeError(`assertion: unexpected ${x} is ${y}`) }) {
if(!Object.is(a, b)) {
thrower(a, b)
}
}
function assertOwnDeep(a, b, thrower=function(x, y){ throw new TypeError(`assertion: unexpected ${x} is ${y}`) }) {
for(const [k, v] of Object.entries(a)) {
if (b.hasOwnProperty(k)) {
assertSome(v, b[k], thrower)
} else {
thrower(a,b)
}
}
}
assert(new A instanceof Array)
assert(Array.isArray(new A))
assert(A.prototype.length === 0)
var a = new A
a.push(3,2,1)
assertOwnDeep([3, 2, 1], a)
a.pop()
assertOwnDeep([3, 2], a)
var b = Array.of.call(A, 1,2,3)
assert(b.constructor === A)
var c = Array.from.call(A, [1,2,3])
assert(c.constructor === A)
var d = A(1,2,3)
assertOwnDeep([1,2,3], d)
assert(d.constructor === A)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment