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.

  • 相关阅读:
    五星评价
    IE9以上 CSS文件因Mime类型不匹配而被忽略 其他浏览器及IE8以下显示正常
    js时间显示设置
    jq手风琴---点击时列表的左边距逐渐减小
    break continue return
    validate插件:验证密码没有空格 用户名是5-10位 至少包含数字和大小写字母中的两种字符
    Commons IO
    Servlet & JSP
    设计模式
    Table of Contents
  • 原文地址:https://www.cnblogs.com/hephec/p/4590013.html
Copyright © 2011-2022 走看看