1. 程式人生 > >JS屬性描述符之Object.defineProperty()定義物件屬性特性

JS屬性描述符之Object.defineProperty()定義物件屬性特性

一、Object.defineProperty的作用

      用來給物件新增屬性,和修改物件中的屬性。

 

二、JS物件中的描述符

      js物件中兩種屬性描述符:資料描述符和存取描述符(訪問描述符)。

      注意事項:

        1、資料描述符和存取描述符都具備configurable、enumerable屬性。

        2、描述符不具備value,writetable,set和get任意一個關鍵字都被認作一個數據描述符。

        3、(value或writetable)和(get和set)不能同時存在,然後只要定義了set和get或其中一個都是一個存取描述符(描述符只能是其中一種)。

     

 

三、Object.defineProperty的使用

var o = {}; // 建立一個新物件

// 在物件中新增一個屬性與資料描述符的示例
Object.defineProperty(o, "a", {
  value : 37,
  writable : true,
  enumerable : true,
  configurable : true
});

// 物件o擁有了屬性a,值為37

// 在物件中新增一個屬性與存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
  get : function(){
    return bValue;
  },
  set : function(newValue){
    bValue = newValue;
  },
  enumerable : true,
  configurable : true
});

o.b = 38;
// 物件o擁有了屬性b,值為38

   1、writable、enumerable、configurable為false的情況

         wirtable:變數不可再被重新賦值

         enumerable: 變數不能在遍歷器例如for...in和Object.keys()中被讀取出來,不可被遍歷

         configurable:變數不可配置,定義為false之後,不能再為該變數定義配置否則報錯。變數被刪除(delete)、修改都會無效。

   2、如果物件的屬性是存取描述符,只會呼叫定義了的set和get(configurable、enumrable)

         在給一個物件屬性做賦值操作,在讀取屬性值時,這個賦值操作賦值的值會被忽略,會去呼叫定義的get方法的值

function Archiver() {
  var temperature = null;
  var archive = [];

  Object.defineProperty(this, 'temperature', {
    
    set: function(value) {
      temperature = value;
      archive.push({ val: temperature });
    }
  });

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

var arc = new Archiver();
arc.temperature = "67"
console.log(arc.temperature); // undefined
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

 

四、關於給物件定義set/get方法  

    vue中可以在computed中給變數定義get/set方法(https://cn.vuejs.org/v2/guide/computed.html),結合v-model雙向資料繫結變數有很多的用處,比如官網的名字的名和姓的拼接。在子元件中我們想要修改父元件傳來的值並及時在dom中渲染的時候。

    

         

computed中給變數定義set/get方法並不是vue中特有的方法,es5中支援了Object.defineProperty,在Object.defineProperty可以給物件的屬性設定為訪問描述符型別,定義set/get方法。我們除了通過這個方法給屬性定義set/get ,還可以通過物件文字語法來定義。

 var myObject = {
	 get a() {
		 return 2
	 }
 }
 myObject.a = 3
 console.log(myObject.a)//2
 console.log(myObject.b)//undefined

  

參考資料:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

http://imweb.io/topic/56d40adc0848801a4ba198ce