Object
の setPrototypeOf
[ES6] を実装してみた。
もちろん最低限 __proto__
が実装されている場合に限る。
※__proto__
がvalueなのかgetter/setterなのかは気にしない
どういう所でsetPrototypeOf
が役に立つのか?
配列みたいなオブジェクトや、禁断の方法でarguments
をいじってみた。
// 配列みたいなオブジェクト
var arrayLike = {length: 3,
0: 'one', 1: 'two', 2: 'three'};
// joinプロパティは無い
console.log(typeof arrayLike.join); // -> undefined
console.log([].join.call(arrayLike, ', ')); // -> onw, two, three
// オブジェクトのプロトタイプを配列に変更
Object.setPrototypeOf(arrayLike, Array.prototype);
// joinプロパティが使える
console.log(typeof arrayLike.join); // -> function
console.log(arrayLike.join(', ')); // -> onw, two, three
// argumentsオブジェクトを配列にしてみる
function getArrayFromArgs() {
// [].slice.call(arguments) の代わり
Object.setPrototypeOf(arguments, Array.prototype);
return arguments.join(', ');
}
console.log(getArrayFromArgs('one', 'two', 'three')); // -> onw, two, three
// argumentsを破壊しても大丈夫かどうか確認してみる
var arrayLike2 = {length: 2, 0: 'one', 1: 'two'};
console.log(typeof arrayLike2.join); // -> undefined
getArrayFromArgs.apply(null, arrayLike2);
console.log(typeof arrayLike2.join); // -> undefined
// applyしても元のオブジェクトには影響しないのでOK
Object.setPrototypeOf
簡易実装
Object.setPrototypeOf
は以下の様になる。
Object.setPrototypeOf
if (!Object.setPrototypeOf) {
Object.defineProperty(Object, 'setPrototypeOf', {
value: function setPrototypeOf(obj, proto) {
obj.__proto__ = proto;
}, writable: true, configurable: true});
}
※基本的にsetPrototypeOf
は黒魔術なので使わなくて済むなら使わない様にネ。
Object.getPrototypeOf
簡易実装
Object.getPrototypeOf
は以下の様になる。
Object.getPrototypeOf
if (!Object.getPrototypeOf) {
Object.defineProperty(Object, 'getPrototypeOf', {
value: function getPrototypeOf(obj) {
return obj.__proto__;
}, writable: true, configurable: true});
}
グローバルな Object
を汚染したくない時
以下の様に通常の関数 getProto
, setProto
を定義して使う。
getProto&setProto
var getProto = Object.getPrototypeOf ? Object.getPrototypeOf :
function getProto(obj) { return obj.__proto__; };
var setProto = Object.setPrototypeOf ? Object.setPrototypeOf :
function setProto(obj, proto) { obj.__proto__ = proto; };
※私は上記を色んな所でコピペして使っています(npmに登録するまでも無い)
参考文献
Object.setPrototypeOf を作る - hogehoge @teramako
Object.setPrototypeOf の作成 - Gist/teramako
Object.setPrototypeOfが実装された - JS.next