zoukankan      html  css  js  c++  java
  • Object.create(): the New Way to Create Objects in JavaScript

     

    There are a lot of ways to create Objects in JavaScript, perhaps even more to integrate inheritance into them. Just when you thought that you've seen every possible way to create JS objects, I'm here to announce that there's yet another: the new Object create() method. Wouldn't you know it, there are some pretty good reasons to use it. But before we get into that, let's get familiar with how it works.

    JS Object Creation Revisited

    Let's quickly review some typical ways that objects are created in JS right now.

    Most people define a constructor function and then create an object by using the new keyword:

    function Car (desc) {
        this.desc = desc;
        this.color = "red";
        this.getInfo = function getInfo() {
            return 'A ' + this.color + ' ' + this.desc + '.';
        };
    }
    
    //instantiate object using the constructor function
    var car = new Car('Porsche boxter');
    car.color = "blue";
    alert(car.getInfo()); //displays 'A blue Porsche boxter.'
    

      

    Winning in the API Economy
     

    A variation on the above theme is to create a constructor function, but to append methods to the Object prototype. That shares the method across objects:

    function Car (desc) {
        this.desc = desc;
        this.color = "red";
    }
    
    Car.prototype.getInfo = function() {
        return 'A ' + this.color + ' ' + this.desc + '.';
    };
    A more sophisticated use of the prototype property is to set it in one fell swoop using either a function or an object literal:
    
    function Car (desc) {
        this.desc = desc;
        this.color = "red";
    }
    
    Car.prototype = {
        getInfo: function() {
          return 'A ' + this.color + ' ' + this.desc + '.';
        },
        drive: function() {
          //DO SOMETHING
        },
        stop: function() {
          //DO SOMETHING
        }
    };
    

      

    The Object.create() Method

    The Object.create() method can just as adeptly create our Car object. It accepts either one or two properties as follows:

    Object.create(proto [, propertiesObject ])
    

      

    The first argument is the prototype to extend. If you aren't subclassing another object then you must pass a null value to the function. The second optional argument is an object containing the object's property descriptors. More on those in a bit.

    We already have a Car prototype, so it makes sense to pass it to Object.create(). Unfortunately, what makes sense isn't always what works!

    function Car (desc) {
        this.desc = desc;
        this.color = "red";
    }
    
    Car.prototype = {
        getInfo: function() {
          return 'A ' + this.color + ' ' + this.desc + '.';
        }
    };
    //instantiate object using the constructor function
    var car =  Object.create(Car.prototype);
    car.color = "blue";
    alert(car.getInfo()); //displays 'A blue undefined.' ??!
    

      

    The description is lost. So why is that? Simple; the create() method only uses the prototype and not the constructor. Hence, Object.create() is an excellent choice for creating an object without going through its constructor. We'll be examining that application in the next instalment. For now, let's tackle how to assign the description.

    The solution of course is to supply it via the second parameter.

    While we're at it, why not assign the color property as well using a Properties Object:

    var Car2 = Object.create(null); //this is an empty object, like {}
    Car2.prototype = {
      getInfo: function() {
        return 'A ' + this.color + ' ' + this.desc + '.';
      }
    };
    
    var car2 = Object.create(Car2.prototype, {
      //value properties
      color:   { writable: true,  configurable:true, value: 'red' },
      //concrete desc value
      rawDesc: { writable: false, configurable:true, value: 'Porsche boxter' },
      // data properties (assigned using getters and setters)
      desc: { 
        configurable:true, 
        get: function ()      { return this.rawDesc.toUpperCase();  },
        set: function (value) { this.rawDesc = value.toLowerCase(); }  
      }
    }); 
    car2.color = 'blue';
    alert(car2.getInfo()); //displays 'A RED PORSCHE BOXTER.'
    

      

    It looks a little confusing at first glance because each property has its own set of properties known collectively as a descriptor. A Descriptor is an object that can be one of two types - Data Descriptors or Accessor Descriptors.

    Data Descriptors

    • writable: Whether the concrete value of the property may be changed. Only applies to data descriptors.
    • configurable: Whether the type of descriptor may be changed, or if the property can be removed.
    • enumerable: Whether the property is listed in a loop through the properties of the object.
    • value: The value of a property. This property only applies to Data descriptors because they reference concrete values, so the value describes the concrete data bound to the property.

    Accessor Descriptors

    Accessor descriptors, on the other hand, proxy access to the concrete value through getter and setter functions. These are useful when some type of transformation or constraints are required. When not set, they'll default to undefined.

    • get (): A function called with no arguments when the property value is requested using dot notation (i,e: obj.prop).
    • set (newValue): A function called with the new value for the property when the user tries to modify the value of the property using dot notation (i,e: obj.prop = 'new value').

    Browser Support

    Most of the major browsers support Object.create(), with the exception of Internet Explorer, which is adding it to version 10.

    What's Next

    The create() method is just one of several new Object methods. We'll be looking at how to use those next time.

  • 相关阅读:
    gorm 更新数据时,0值会被忽略
    xshell评估过期解决办法
    安装zoom
    aria2 加速百度网盘下载
    ubuntu17.10 安装firefox的flash
    c++ 回调函数使用
    ubuntu17 安装中文输入法
    ubuntu python3.6 找不到_sqlite3
    linux 获取CPU个数
    centos7 yum与Python3冲突
  • 原文地址:https://www.cnblogs.com/hephec/p/4590013.html
Copyright © 2011-2022 走看看