阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      JS Object.create()

      **Object.create()**方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

      The source for this interactive example is stored in a GitHub repository. If you’d like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

      语法

      Object.create(proto[, propertiesObject])
      

      参数

      proto

      新创建对象的原型对象。

      propertiesObject

      可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。

      返回值

      一个新对象,带着指定的原型对象和属性。

      例外

      如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。

      例子

      用 Object.create实现类式继承

      下面的例子演示了如何使用Object.create()来实现类式继承。这是一个所有版本JavaScript都支持的单继承。

      // Shape - 父类(superclass)
      function Shape() {
        this.x = 0;
        this.y = 0;
      }
      
      // 父类的方法
      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.
      }
      
      // 子类续承父类
      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);
      }
      
      // 继承一个类
      MyClass.prototype = Object.create(SuperClass.prototype);
      // 混合其它
      Object.assign(MyClass.prototype, OtherSuperClass.prototype);
      // 重新指定constructor
      MyClass.prototype.constructor = MyClass;
      
      MyClass.prototype.myMethod = function() {
           // do a thing
      };
      
      

      Object.assign 会把  OtherSuperClass原型上的函数拷贝到 MyClass原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。Object.assign 是在 ES2015 引入的,且可用 polyfilled。要支持旧浏览器的话,可用使用 jQuery.extend() 或者 _.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 涵盖了主要的应用场景,它创建一个已经选择了原型的新对象,但没有把第二个参数考虑在内。

      请注意,尽管在 ES5 中 Object.create支持设置为[[Prototype]]null,但因为那些ECMAScript5以前版本限制,此 polyfill 无法支持该特性。

      if (typeof Object.create !== "function") {
          Object.create = function (proto, propertiesObject) {
              if (typeof proto !== 'object' && typeof proto !== 'function') {
                  throw new TypeError('Object prototype may only be an Object: ' + proto);
              } else if (proto === null) {
                  throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
              }
      
              if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
      
              function F() {}
              F.prototype = proto;
      
              return new F();
          };
      }
      

      规范

      SpecificationStatusComment
      ECMAScript 5.1 (ECMA-262) Object.createStandardInitial definition. Implemented in JavaScript 1.8.5.
      ECMAScript 2015 (6th Edition, ECMA-262)Object.createStandard
      ECMAScript Latest Draft (ECMA-262)Object.createDraft

      相关链接

      目录
      目录