LoginSignup
6
4

More than 5 years have passed since last update.

[JavaScript] Object.setPrototypeOf の簡易実装

Posted at

ObjectsetPrototypeOf [ES6] を実装してみた。

もちろん最低限 __proto__ が実装されている場合に限る。
__proto__がvalueなのかgetter/setterなのかは気にしない

javascript.jpg

どういう所で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

prototype.__proto__ - js STUDIO

Google流 JavaScript におけるクラス定義の実現方法

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4