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 は以下の様になる。
if (!Object.setPrototypeOf) {
Object.defineProperty(Object, 'setPrototypeOf', {
value: function setPrototypeOf(obj, proto) {
obj.__proto__ = proto;
}, writable: true, configurable: true});
}
※基本的にsetPrototypeOfは黒魔術なので使わなくて済むなら使わない様にネ。
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 を定義して使う。
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]
(http://d.hatena.ne.jp/teramako/20130319/p1)
[Object.setPrototypeOf の作成 - Gist/teramako]
(https://gist.github.com/teramako/5193838)
[Object.setPrototypeOfが実装された - JS.next]
(http://js-next.hatenablog.com/entry/2014/01/20/194125)
[prototype.__proto__ - js STUDIO]
(http://js.studio-kingdom.com/javascript/object/prototype_proto)
[Google流 JavaScript におけるクラス定義の実現方法]
(http://www.yunabe.jp/docs/javascript_class_in_google.html)
