【问题标题】:Data Descriptors in literal notation (object creation)文字表示法中的数据描述符(对象创建)
【发布时间】:2014-06-19 13:03:01
【问题描述】:

我知道 ECMAScript5 有两种创建对象的方法。

1/ 文字表示法(默认情况下)将所有内部数据属性设置为 true(可写、可配置和可枚举。

2/ 使用 Object.create 方法(默认情况下)将所有数据描述符设置为 false。

在文字表示法中将 enumerable 设置为 false 是否有效?在 object2 上执行此操作时,Object.keys(obj2) 不应该返回一个空数组吗?

var obj1 = Object.create(null, {
  'name': {value: 'first object name'},
  'surename': {value: 'first object surname', enumerable: true, configurable: true}
});

var obj2 = {'x': {value: 10, enumerable: false}};

console.log(Object.keys(obj1)); // ["surename"] 
console.log(Object.keys(obj2)); // ["x"]

JsFiddle link

【问题讨论】:

    标签: javascript ecmascript-5


    【解决方案1】:

    我也为此上下搜索,但找不到任何东西。但是,您可以定义 getter 和 setter 函数,如果这就是您所需要的,就像这样:

    var x = {
      y: 6,
      get foo() {
        return this.y + 10;
      },
      set bar(value) {
        this.y = foo - 1;
      }
    };
    
    x.y; // 6
    x.foo; // 16
    x.bar = 8;
    x.y; // 7
    x.foo; // 17
    

    我还定义了一个小实用程序来简化以文字表示法定义属性。这里是:

    /*
     * Facilitates defining properties with advanced attributes in literal notation.
     *
     * Example:
     *   var foo = {
     *     x: 6,
     *     bar: new Property({
     *       enumerable: false,
     *       get: function () {
     *         return this.x + 1
     *       }
     *     })
     *   }
     *   foo.bar // value is an object of type Property
     *   Properties.eval(foo)
     *   foo.bar // value is now 7
     */
    
    'use strict'
    
    /**
     * Constructor.
     *
     * @param {object} descriptor
     * the property descriptor, in the format used by <code>Object.defineProperty</code>
     *
     * @returns {Property}
     *
     * @see Object.defineProperty
     */
    var Property = function (descriptor) {
      this.descriptor = descriptor
      Object.freeze(this)
    }
    
    Property.prototype.toString = function () {
      return 'Property'
    }
    
    var Properties = new Object(null)
    
    /**
     * Replace all properties of type <code>Property</code> contained in the
     * specified object with the value associated with the <code>Property</code>.
     *
     * @param {object} object
     * the object
     */
    Properties.eval = function (object) {
      // recursive
      for (var propertyName in object) {
        if (object.hasOwnProperty(propertyName)) {
          var property = object[propertyName]
          if (property instanceof Property) {
            Object.defineProperty(object, propertyName, property.descriptor)
            property = object[propertyName]
          }
          if (property instanceof Object) {
            Properties.eval(property)
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      基本上,用这一行:

      var obj2 = {'x': {value: 10, enumerable: false}};
      

      您正在声明变量obj2,它是一个具有一个属性x 的对象,其值是一个具有两个属性的对象:valueenumerableObject.create() 是函数,它只是使用文字符号来定义正在构造的对象的属性。

      【讨论】:

        【解决方案3】:

        在文字表示法中将 enumerable 设置为 false 是否有效?在object2 上执行此操作时,Object.keys(obj2) 不应该返回一个空数组吗?

        取决于您所说的“有效”。正确的答案是它是不可能(至少在 ES5 中),所以你只是定义了一个具有两个属性的对象,每个属性都有一个对象作为值。

        看看obj.x

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-19
          • 2014-02-11
          • 1970-01-01
          • 2012-04-20
          • 2013-05-26
          • 2016-08-04
          • 1970-01-01
          • 2012-03-27
          相关资源
          最近更新 更多