JavaScript深刻理解對象方法——Object.defineProperties()

Object.defineProperties()

Object.defineProperties() 方法直接在一個對象上定義新的屬性或修改現有屬性,並返回該對象。ide

語法

Object.defineProperties(obj, props)函數

參數

  • obj
    在其上定義或修改屬性的對象。
  • props
    要定義其可枚舉屬性或修改的屬性描述符的對象。對象中存在的屬性描述符主要有兩種:數據描述符和訪問器描述符(更多詳情,請參閱Object.defineProperty())。描述符具備如下鍵:
  • configurable
    true 當且僅當該屬性描述符的類型能夠被改變而且該屬性能夠從對應對象中刪除。默認爲 false
  • enumerable
    true 當且僅當在枚舉相應對象上的屬性時該屬性顯現。默認爲 false
  • value
    與屬性關聯的值。能夠是任何有效的JavaScript值(數字,對象,函數等)。默認爲 undefined.
  • writable
    true當且僅當與該屬性相關聯的值能夠用assignment operator改變時。默認爲 false
  • get
    做爲該屬性的 getter 函數,若是沒有 getter 則爲undefined。函數返回值將被用做屬性的值。默認爲 undefined
  • set
    做爲屬性的 setter 函數,若是沒有 setter 則爲undefined。函數將僅接受參數賦值給該屬性的新值。默認爲 undefined

返回值

傳遞給函數的對象。prototype

描述

Object.defineProperties本質上定義了obj 對象上props的可枚舉屬性相對應的全部屬性。code

例子

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

Polyfill

假設一個原始的執行環境,全部的名稱和屬性都引用它們的初始值,Object.defineProperties幾乎徹底等同於(注意isCallable中的註釋)如下JavaScript中的從新實現:對象

function defineProperties(obj, properties) {
  function convertToDescriptor(desc) {
    function hasProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }

    function isCallable(v) {
      // NB: modify as necessary if other values than functions are callable.
      return typeof v === 'function';
    }

    if (typeof desc !== 'object' || desc === null)
      throw new TypeError('bad desc');

    var d = {};

    if (hasProperty(desc, 'enumerable'))
      d.enumerable = !!desc.enumerable;
    if (hasProperty(desc, 'configurable'))
      d.configurable = !!desc.configurable;
    if (hasProperty(desc, 'value'))
      d.value = desc.value;
    if (hasProperty(desc, 'writable'))
      d.writable = !!desc.writable;
    if (hasProperty(desc, 'get')) {
      var g = desc.get;

      if (!isCallable(g) && typeof g !== 'undefined')
        throw new TypeError('bad get');
      d.get = g;
    }
    if (hasProperty(desc, 'set')) {
      var s = desc.set;
      if (!isCallable(s) && typeof s !== 'undefined')
        throw new TypeError('bad set');
      d.set = s;
    }

    if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d))
      throw new TypeError('identity-confused descriptor');

    return d;
  }

  if (typeof obj !== 'object' || obj === null)
    throw new TypeError('bad obj');

  properties = Object(properties);

  var keys = Object.keys(properties);
  var descs = [];

  for (var i = 0; i < keys.length; i++)
    descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);

  for (var i = 0; i < descs.length; i++)
    Object.defineProperty(obj, descs[i][0], descs[i][1]);

  return obj;
}
相關文章
相關標籤/搜索