成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

defineProperty AND defineProperties

Shihira / 2759人閱讀

摘要:返回值被傳遞給函數(shù)的對(duì)象。描述符必須是這兩種形式之一不能同時(shí)是兩者。默認(rèn)為實(shí)現(xiàn)內(nèi)部原理數(shù)據(jù)描述符同時(shí)具有以下可選鍵值與屬性關(guān)聯(lián)的值。一個(gè)沒(méi)有定義的屬性被稱為通用的,并被鍵入為一個(gè)數(shù)據(jù)描述符。

Object.defineProperty(obj, prop, descriptor) 該方法允許精確添加或修改對(duì)象的屬性。通過(guò)賦值來(lái)添加的普通屬性會(huì)創(chuàng)建在屬性枚舉期間顯示的屬性(for...in Object.keys 方法), 這些值可以被改變,也可以被刪除。這種方法允許這些額外的細(xì)節(jié)從默認(rèn)值改變。默認(rèn)情況下,使用Object.defineProperty()添加的屬性值是不可變的。

`Object.defineProperties(obj, props)`、` Object.defineProperties`本質(zhì)上定義了`obj` 對(duì)象上`props`的`可枚舉屬性`相對(duì)應(yīng)的所有屬性。
`Object.defineProperties(obj, props)`實(shí)現(xiàn)

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;
}

### 參數(shù)

`obj `在其上定義或修改屬性的對(duì)象。
`prop` 要定義或修改的屬性的名稱。
`descriptor` 將被定義或修改的屬性描述符。
`返回值 ` `被傳遞給函數(shù)的對(duì)象`。
`props` 要定義其可枚舉屬性或修改的屬性描述符的對(duì)象。對(duì)象中存在的屬性描述符主要有兩種:`數(shù)據(jù)描述符`和`訪問(wèn)器描述符`。描述符具有以下鍵:
數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:
對(duì)象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符。數(shù)據(jù)描述符是一個(gè)具有值的屬性,該值可能是可寫(xiě)的,也可能不是可寫(xiě)的。`存取描述符`是由`getter-setter`函數(shù)對(duì)描述的屬性。描述符必須是這兩種形式之一;不能同時(shí)是兩者。
  `configurable` true 當(dāng)且僅當(dāng)該屬性描述符的類型可以被改變并且該屬性可以從對(duì)應(yīng)對(duì)象中刪除。`默認(rèn)為 false`
  `enumerable` true 當(dāng)且僅當(dāng)在枚舉相應(yīng)對(duì)象上的屬性時(shí)該屬性顯現(xiàn)。` 默認(rèn)為 false`  for ... in obj  obj.keys() 實(shí)現(xiàn)內(nèi)部原理
數(shù)據(jù)描述符同時(shí)具有以下可選鍵值:
  `value` 與屬性關(guān)聯(lián)的值??梢允侨魏斡行У腏avaScript值(數(shù)字,對(duì)象,函數(shù)等)。 ` 默認(rèn)為 undefined`.
  `writable` true當(dāng)且僅當(dāng)與該屬性相關(guān)聯(lián)的值可以用assignment operator改變時(shí)。 `默認(rèn)為 false`  當(dāng)需要些一些不可以被更改的屬性時(shí)可以使用
存取描述符同時(shí)具有以下可選鍵值:
  `get `作為該屬性的 getter 函數(shù),如果沒(méi)有 getter 則為undefined。函數(shù)返回值將被用作屬性的值。默認(rèn)為 undefined
  `set `作為屬性的 setter 函數(shù),如果沒(méi)有 setter 則為undefined。函數(shù)將僅接受參數(shù)賦值給該屬性的新值。默認(rèn)為 undefined

如果一個(gè)描述符不具有value,writable,get 和 set 任意一個(gè)關(guān)鍵字,那么它將被認(rèn)為是一個(gè)數(shù)據(jù)描述符。如果一個(gè)描述符同時(shí)有(value或writable)和(get或set)關(guān)鍵字,將會(huì)產(chǎn)生一個(gè)異常。


記住,這些選項(xiàng)不一定是自身屬性,如果是繼承來(lái)的也要考慮。為了確認(rèn)保留這些默認(rèn)值,你可能要在這之前凍結(jié) Object.prototype,明確指定所有的選項(xiàng),或者將__proto__屬性指向null。
   使用 __proto__
   var obj = {};
   var descriptor = Object.create(null); // 沒(méi)有繼承的屬性
   // 默認(rèn)沒(méi)有 enumerable,沒(méi)有 configurable,沒(méi)有 writable
   descriptor.value = "static";
   Object.defineProperty(obj, "key", descriptor);

   // 顯式
   Object.defineProperty(obj, "key", {
     enumerable: false,
     configurable: false,
     writable: false,
     value: "static"
   });

   // 循環(huán)使用同一對(duì)象
   function withValue(value) {
     var d = withValue.d || (
       withValue.d = {
         enumerable: false,
         writable: false,
         configurable: false,
         value: null
       }
     );
     d.value = value;
     return d;
   }
   // ... 并且 ...
   Object.defineProperty(obj, "key", withValue("static")); 
   // 如果 freeze 可用, 防止代碼添加或刪除對(duì)象原型的屬性
   // (value, get, set, enumerable, writable, configurable)
   (Object.freeze||Object)(Object.prototype);
###作用:
☆創(chuàng)建屬性
當(dāng)描述符中省略某些字段時(shí),這些字段將使用它們的默認(rèn)值。擁有布爾值的字段的默認(rèn)值都是false。value,get和set字段的默認(rèn)值為undefined。一個(gè)沒(méi)有g(shù)et/set/value/writable定義的屬性被稱為“通用的”,并被“鍵入”為一個(gè)數(shù)據(jù)描述符。
```
var o = {}; // 創(chuàng)建一個(gè)新對(duì)象

在對(duì)象中添加一個(gè)屬性與數(shù)據(jù)描述符的示例
Object.defineProperty(o, "a", {
  value : 37,
  writable : true,
  enumerable : true,
  configurable : true
});

// 對(duì)象o擁有了屬性a,值為37

// 在對(duì)象中添加一個(gè)屬性與存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
  get : function(){
    return bValue;
  },
  set : function(newValue){
    bValue = newValue;
  },
  enumerable : true,
  configurable : true
});
o.b = 38;
// 對(duì)象o擁有了屬性b,值為38
// 改變bValue也無(wú)法改變o.b
console.log(bValue);
  
// o.b的值現(xiàn)在總是與bValue相同,除非重新定義o.b

// 數(shù)據(jù)描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
  value: 0x9f91102, 
  get: function() { 
    return 0xdeadbeef; 
  } 
});
throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors
```
☆修改屬性
如果屬性已經(jīng)存在,`Object.defineProperty()`將嘗試根據(jù)描述符中的值以及對(duì)象當(dāng)前的配置來(lái)修改這個(gè)屬性。如果舊描述符將其`configurable` 屬性設(shè)置為`false`,則該屬性被認(rèn)為是`“不可配置的”`,并且沒(méi)有屬性可以被改變(除了單向改變 `writable` 為 `false`)。當(dāng)屬性不可配置時(shí),不能在數(shù)據(jù)和訪問(wèn)器屬性類型之間切換。
當(dāng)試圖改變不可配置屬性(除了writable 屬性之外)的值時(shí)會(huì)拋出{jsxref("TypeError")}},除非當(dāng)前值和新值相同。
1 `Writable` 屬性 當(dāng)writable屬性設(shè)置為false時(shí),該屬性被稱為“不可寫(xiě)”。它不能被重新分配。 試圖寫(xiě)入非可寫(xiě)屬性不會(huì)改變它,也不會(huì)引發(fā)錯(cuò)誤。
```
var o = {}; // Creates a new object

Object.defineProperty(o, "a", {
  value: 37,
  writable: false
});

console.log(o.a); // logs 37
o.a = 25; // No error thrown
// (it would throw in strict mode,
// even if the value had been the same)
console.log(o.a); // logs 37. The assignment didn"t work.

// strict mode
(function() {
  "use strict";
  var o = {};
  Object.defineProperty(o, "b", {
    value: 2,
    writable: false
  });
  o.b = 3; // throws TypeError: "b" is read-only
  return o.b; // returns 2 without the line above
}());
   
  2 `Enumerable `特性 enumerable定義了對(duì)象的屬性是否可以在 for...in 循環(huán)和 Object.keys() 中被枚舉默認(rèn)是true。
  var o = {};
  Object.defineProperty(o, "a", { value : 1, enumerable:true });
  Object.defineProperty(o, "b", { value : 2, enumerable:false });
  Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
  o.d = 4; // 如果使用直接賦值的方式創(chuàng)建對(duì)象的屬性,則這個(gè)屬性的enumerable為true

  for (var i in o) {    
    console.log(i);  
  }
  打印 "a" 和 "d" (in undefined order)

  Object.keys(o); // ["a", "d"]

  o.propertyIsEnumerable("a"); // true
  o.propertyIsEnumerable("b"); // false
  o.propertyIsEnumerable("c"); // false
  ```
  3 Configurable 特性 configurable特性表示對(duì)象的屬性是否可以被刪除,以及除writable特性外的其他特性是否可以被修改。
  如果o.a的configurable屬性為true,則不會(huì)拋出任何錯(cuò)誤,并且該屬性將在最后被刪除。
    var o = {};
    Object.defineProperty(o, "a", { get : function(){return 1;},  configurable : false } ); //為true時(shí),不會(huì)報(bào)錯(cuò) 結(jié)果為12  undefined(可以刪除)

    // throws a TypeError Cannot redefine property: a
    Object.defineProperty(o, "a", {configurable : true}); 
    // // throws a TypeError
    Object.defineProperty(o, "a", {enumerable : true}); 
    // // throws a TypeError (set was undefined previously) 
    Object.defineProperty(o, "a", {set : function(){}}); 
    // // throws a TypeError (even though the new get does exactly the same thing) 
    Object.defineProperty(o, "a", {get : function(){return 1;}});
    // // throws a TypeError
    Object.defineProperty(o, "a", {value : 12});

    console.log(o.a); // logs 1
    delete o.a; // Nothing happens
    console.log(o.a); // logs 1
```
  ☆  添加多個(gè)屬性和默認(rèn)值
  考慮特性被賦予的默認(rèn)特性值非常重要,通常,使用點(diǎn)運(yùn)算符和Object.defineProperty()為對(duì)象的屬性賦值時(shí),數(shù)據(jù)描述符中的屬性默認(rèn)值是不同的,如下例所示。
  
  ```
  var o = {};

  o.a = 1;
  // 等同于 :
  Object.defineProperty(o, "a", {
    value : 1,
    writable : true,
    configurable : true,
    enumerable : true
  });


  // 另一方面,
  Object.defineProperty(o, "a", { value : 1 });
  // 等同于 :
  Object.defineProperty(o, "a", {
    value : 1,
    writable : false,
    configurable : false,
    enumerable : false
  });
  ```
  ☆ 一般的 `Setter` 和 `Getters`
  下面的例子展示了如何實(shí)現(xiàn)一個(gè)自存檔對(duì)象。 當(dāng)設(shè)置temperature 屬性時(shí),archive 數(shù)組會(huì)獲取日志條目。
  ```
  function Archiver() {
    var temperature = null;
    var archive = [];

    Object.defineProperty(this, "temperature", {
      get: function() {
        console.log("get!");
        return temperature;
      },
      set: function(value) {
        temperature = value;
        archive.push({ val: temperature });
      }
    });

    this.getArchive = function() { return archive; };
  }

  var arc = new Archiver();
  arc.temperature; // "get!"
  arc.temperature = 11;
  arc.temperature = 13;
  arc.getArchive(); // [{ val: 11 }, { val: 13 }]
  ```
  // 或
  
  ```
  var pattern = {
      get: function () {
          return "I alway return this string,whatever you have assigned";
      },
      set: function () {
          this.myname = "this is my name string";
      }
  };


  function TestDefineSetAndGet() {
      Object.defineProperty(this, "myproperty", pattern);
  }


  var instance = new TestDefineSetAndGet();
  instance.myproperty = "test";

  // "I alway return this string,whatever you have assigned"
  console.log(instance.myproperty);
  // "this is my name string"
  console.log(instance.myname);
  ```
  
  ☆ ☆兼容性問(wèn)題
  1 數(shù)組的 length 屬性重定義是可能的,但是會(huì)受到一般的重定義限制。(length 屬性初始為 non-configurable,non-enumerable 以及 writable。對(duì)于一個(gè)內(nèi)容不變的數(shù)組,改變其 length 屬性的值或者使它變?yōu)?non-writable 是可能的。但是改變其可枚舉性和可配置性或者當(dāng)它是 non-writable 時(shí)嘗試改變它的值或是可寫(xiě)性,這兩者都是不允許的。)然而,并不是所有的瀏覽器都允許 Array.length 的重定義。

  在 Firefox 4 至 22 版本中嘗試去重定義數(shù)組的 length 屬性都會(huì)拋出一個(gè) TypeError 異常。

  有些版本的Chrome中,Object.defineProperty() 在某些情況下會(huì)忽略不同于數(shù)組當(dāng)前l(fā)ength屬性的length值。有些情況下改變可寫(xiě)性并不起作用(也不拋出異常)。同時(shí),比如Array.prototype.push的一些數(shù)組操作方法也不會(huì)考慮不可讀的length屬性。

  有些版本的Safari中,Object.defineProperty()  在某些情況下會(huì)忽略不同于數(shù)組當(dāng)前l(fā)ength屬性的length值。嘗試改變可寫(xiě)性的操作會(huì)正常執(zhí)行而不拋出錯(cuò)誤,但事實(shí)上并未改變屬性的可寫(xiě)性。

  只在Internet Explorer 9及以后版本和Firefox 23及以后版本中,才完整地正確地支持?jǐn)?shù)組length屬性的重新定義。目前不要依賴于重定義數(shù)組length 屬性能夠起作用,或在特定情形下起作用。與此同時(shí),即使你能夠依賴于它,你也沒(méi)有合適的理由這樣做。
  2 Internet Explorer 8 具體案例
  Internet Explorer 8 實(shí)現(xiàn)了 Object.defineProperty() 方法,但 只能在 DOM 對(duì)象上使用。 需要注意的一些事情:

  嘗試在原生對(duì)象上使用 Object.defineProperty()會(huì)報(bào)錯(cuò)。
  屬性特性必須設(shè)置一些特定的值。對(duì)于數(shù)據(jù)屬性描述符,configurable, enumerable 和 writable 特性必須全部設(shè)置為 true;對(duì)于訪問(wèn)器屬性描述符,configurable 必須設(shè)置為 true,enumerable 必須設(shè)置為 false。(?) 任何試圖提供其他值(?)將導(dǎo)致一個(gè)錯(cuò)誤拋出。
  重新配置一個(gè)屬性首先需要?jiǎng)h除該屬性。如果屬性沒(méi)有刪除,就如同重新配置前的嘗試。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96101.html

相關(guān)文章

  • 詳解JavaScript之神奇的Object.defineProperty

    摘要:與當(dāng)與同時(shí)為時(shí),屬性不能重新使用定義,嚴(yán)格模式下會(huì)報(bào)錯(cuò)示例云麒報(bào)錯(cuò)當(dāng)或者為時(shí),屬性可以重新使用定義,這一點(diǎn)讀者不妨自行測(cè)試。 摘要: JavaScript有個(gè)很神奇的Object.defineProperty(),了解一下? =與Object.defineProperty 為JavaScript對(duì)象新增或者修改屬性,有兩種不同方式:直接使用=賦值或者使用Object.definePro...

    baishancloud 評(píng)論0 收藏0
  • JS屬性特性(屬性描述符)

    摘要:概念中定義了一個(gè)名叫屬性描述符的對(duì)象,用于描述了的各種特征。只指定則表示屬性為只讀屬性。使用屬性描述符對(duì)象只能在或中使用。修改已有的屬性會(huì)拋出類型錯(cuò)誤異常添加屬性會(huì)拋出類型錯(cuò)誤異常不能修屬性結(jié)語(yǔ)我對(duì)屬性描述符很不熟悉,主要是因?yàn)槠綍r(shí)用得少。 概念 ECMAScript 5 中定義了一個(gè)名叫屬性描述符的對(duì)象,用于描述了的各種特征。屬性描述符對(duì)象有4個(gè)屬性: configurable:可...

    yeyan1996 評(píng)論0 收藏0
  • JavaScript深入理解對(duì)象方法——Object.defineProperty()

    摘要:返回值被傳遞給函數(shù)的對(duì)象。描述該方法允許精確添加或修改對(duì)象的屬性。描述符必須是兩種形式之一不能同時(shí)是兩者??梢允侨魏斡行У闹禂?shù)值,對(duì)象,函數(shù)等。該方法返回值被用作屬性值。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。 Object.defineProperties() Object.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性...

    woshicixide 評(píng)論0 收藏0
  • JS進(jìn)階篇--JS apply的巧妙用法以及擴(kuò)展到Object.defineProperty的使用

    摘要:的使用對(duì)象是由多個(gè)名值對(duì)組成的無(wú)序的集合。目標(biāo)屬性所擁有的特性返回值傳入函數(shù)的對(duì)象。是一種獲得屬性值的方法是一種設(shè)置屬性值的方法。參考相關(guān)閱讀鏈接基礎(chǔ)篇中的可枚舉屬性與不可枚舉屬性以及擴(kuò)展 Math.max 實(shí)現(xiàn)得到數(shù)組中最大的一項(xiàng) var array = [1,2,3,4,5]; var max = Math.max.apply(null, array); console.log(m...

    jasperyang 評(píng)論0 收藏0
  • 屬性描述對(duì)象

    摘要:可枚舉性屬性是一個(gè)布爾值,表示目標(biāo)屬性是否可枚舉。可配置性返回一個(gè)布爾值,決定了是否可以修改屬性描述對(duì)象。其中,存值函數(shù)稱為,使用屬性描述對(duì)象的屬性取值函數(shù)稱為,使用屬性描述對(duì)象的屬性。 JavaScript 提供了一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來(lái)描述對(duì)象的屬性,控制它的行為,比如該屬性是否可寫(xiě)、可枚舉等等。這個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu)稱為屬性描述對(duì)象(attributes object)。每個(gè)屬性都有自己...

    developerworks 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Shihira

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<