JavaScriptは対象を深く理解する方法——Object.creat()


Object.creat()Object.create()方法は、指定されたプロトタイプオブジェクトと属性を使用して新しいオブジェクトを作成します.
構文
Object.create(proto[, propertiesObject])
  • proto新規作成対象の原型オブジェクト.
  • propertiesObjectはオプションです.undefinedとして指定されていない場合、新規作成対象に追加するエニュメレート・属性(すなわち、自身が定義する属性であり、プロトタイプチェーン上のエニュメレート・属性ではない)オブジェクトの属性記述子および対応する属性名である.これらの属性はObject.defineProperties()の第2のパラメータに対応する.
  • 戻り値
    プロトタイプオブジェクトに新しい属性を追加したオブジェクト.
    例外propertiesObjectパラメータがnullまたはオブジェクトでない場合、TypeErrorに異常がある.

    クラス継承はObject.createで実現される.
    以下の例は、クラス継承を達成するためにObject.create()をどのように使用するかを示している.これはJavaScriptのすべてのバージョンがサポートされている単一継承です.
    // Shape - superclass
    function Shape() {
      this.x = 0;
      this.y = 0;
    }
    
    // superclass method
    Shape.prototype.move = function(x, y) {
      this.x += x;
      this.y += y;
      console.info('Shape moved.');
    };
    
    // Rectangle - subclass
    function Rectangle() {
      Shape.call(this); // call super constructor.
    }
    
    // subclass extends superclass
    Rectangle.prototype = Object.create(Shape.prototype);
    Rectangle.prototype.constructor = Rectangle;
    
    var rect = new Rectangle();
    
    console.log('Is rect an instance of Rectangle?',
      rect instanceof Rectangle); // true
    console.log('Is rect an instance of Shape?',
      rect instanceof Shape); // true
    rect.move(1, 1); // Outputs, 'Shape moved.'
    複数のオブジェクトを継承したい場合は、混入の方法を使用することができます.
    function MyClass() {
         SuperClass.call(this);
         OtherSuperClass.call(this);
    }
    
    // inherit one class
    MyClass.prototype = Object.create(SuperClass.prototype);
    // mixin another
    Object.assign(MyClass.prototype, OtherSuperClass.prototype);
    // re-assign constructor
    MyClass.prototype.constructor = MyClass;
    
    MyClass.prototype.myMethod = function() {
         // do a thing
    };
    Object.assignはOtherSuperClassプロトタイプの関数をMyClassプロトタイプにコピーして、MyClassのすべてのインスタンスをOtherSuperClassの方法で使用できるようにします.Object.assignはES 2015に導入され、polyfilledが利用可能です.古いブラウザをサポートするには、jQuery.exted()または_.assign()Object.createpropertyObjectパラメータを使用します.
    var o;
    
    //        null    
    o = Object.create(null);
    
    
    o = {};
    //                 :
    o = Object.create(Object.prototype);
    
    
    o = Object.create(Object.prototype, {
      // foo             
      foo: { 
        writable:true,
        configurable:true,
        value: "hello" 
      },
      // bar              
      bar: {
        configurable: false,
        get: function() { return 10 },
        set: function(value) {
          console.log("Setting `o.bar` to", value);
        }
      }
    });
    
    
    function Constructor(){}
    o = new Constructor();
    //          :
    o = Object.create(Constructor.prototype);
    //   ,   Constructor           ,Object.create        
    
    
    //               ,       p   
    o = Object.create({}, { p: { value: 42 } })
    
    //            false,    p    ,    ,     :
    o.p = 24
    o.p
    //42
    
    o.q = 12
    for (var prop in o) {
       console.log(prop)
    }
    //"q"
    
    delete o.p
    //false
    
    //       ,    ,      p
    o2 = Object.create({}, {
      p: {
        value: 42, 
        writable: true,
        enumerable: true,
        configurable: true 
      } 
    });
    Polyfill
    このpolyfillは主要な応用シーンをカバーしており、プロトタイプが選択された新しいオブジェクトを作成したが、第二のパラメータを考慮していない.
    なお、ES 5においてObject.create[[Prototype]]に設定されているにもかかわらず、それらのECMAScript 5の以前のバージョン制限のため、このpolyfillはこの特性をサポートできない.
    if (typeof Object.create !== "function") {
        Object.create = function (proto, propertiesObject) {
            if (!(proto === null || typeof proto === "object" || typeof proto === "function")) {
                throw TypeError('Argument must be an object, or null');
            }
            var temp = new Object();
            temp.__proto__ = proto;
            if(typeof propertiesObject ==="object")
                Object.defineProperties(temp,propertiesObject);
            return temp;
        };
    }