JavaScript中的Object.defineProperty()函數

       花了一個半小時寫的,請懷着一顆感恩的心閱讀,謝謝!

       我在說明一個事物和概念時,喜歡先上代碼看到效果,然後再解釋概念。

       ES5新增的函數Object.defineProperty(),可以給JavaScript對象增加屬性。啊……,那以前的json對象不是本來就可以嗎。爲何還得搞出個這麼複雜的函數來做這個事情。

一、代碼部分(先上代碼):

1、回顧一下json對象增加屬性

如果沒有問題,可以不看本段。

//定義一個對象

Var person = {};

//給對象增加一個屬性

Person.age = 12;

Person.name = “張三瘋”;

Person.isAdult =”未成年”;

 

Ok,沒有問題。但是:

1)、思考一個問題,age屬性的值應該是有個用有效範圍的(如:0-150),但是,這樣增加的屬性沒法限制age屬性的取值範圍

2)、如果age屬性的變化,會引起其它屬性的變化,即其它屬性的值會隨着age的變化而變化,這樣沒法很好控制,而且很容易控制不好。如以上屬性isAdult的值,不能直接隨便賦值,而是age的值變化後,isAdult 的值會跟着變化。

     

2、如何用 Object.defineProperty()函數給對象增加屬性。

 

Var person = {};

Object.defineProperty(person ,"name",{

    value:"張三瘋",

    writable:false//屬性name不能修改

});

Console.log(person.name);//張三瘋

person.name = "隔壁老王"; //修改不成功

console.log(person.name);//張三瘋

 

沒想到吧,我們還可以讓某些屬性的值是隻讀的。

 

    3、如果用 Object.defineProperty()進行給對象增加屬性,該屬性的取值是可控的,而且會影響其它屬性的變化。

  注意:以下代碼中,在對象的定義中,寫的是帶下劃線的:_age,而在defineProperty()函數裏寫的屬性名是不帶下劃線的:age,外部使用該對象的屬性時,用不帶下劃線的:


let person = {
    _age:12,
    isAdult:"未成年"
};
Object.defineProperty(person,"age",{
    get:function(){
        return this._age;
    },
    set:function(newValue){
        //此判斷是限制屬性的取值範圍是0-150之間
        if(newValue<0 || newValue>150){
            return;
        }
        this._age = newValue;
        //此判斷是 _age屬性的值影響isAdult的值。
        if(this._age>=18){
            this.isAdult = "已成年";
        }else{
            this.isAdult = "未成年";
        }
    }
});

person.age = 16; //此句話會調用 set函數。
console.log(person.age);//此句話對調動get函數
console.log(person.isAdult);//未成年

person.age = 25; //此句話會調用 set函數。
console.log(person.age);//此句話對調動get函數
console.log(person.isAdult);//已成年

 

二、概念:

     1、普及一個概念,JavaScript的屬性有三種類型(重點看前兩點):

          1)、命名數據屬性:擁有一個確定的值的屬性。這也是最常見的屬性。

          2)、命名訪問器屬性:通過getter和setter進行讀取和賦值的屬性(這是今天重點要說的)

          3)、內部屬性:由JavaScript引擎內部使用的屬性,不能通過JavaScript代碼直接訪問到,不過可以通過一些方法間接的讀取和設置。比如,每個對象都有一個內部屬性[[Prototype]],你不能直接訪問這個屬性,但可以通過Object.getPrototypeOf()方法間接的讀取到它的值。雖然內部屬性通常用一個雙呂括號包圍的名稱來表示,但實際上這並不是它們的名字,它們是一種抽象操作,是不可見的,根本沒有上面兩種屬性有的那種字符串類型的屬性

 

    2、Object.defineProperty()的作用就是直接在一個對象上定義一個新屬性,或者修改一個已經存在的屬性。

    3、Object.defineProperty()函數的格式:

Object.defineProperty(obj, prop, desc)

參數:

Obj:表示增加屬性的對象

Prop:屬性名

Desc:屬性描述符

   4、屬性描述符

1)、概念:

 屬性描述符,是對當前屬性的描述(包括設置)。

如 以上代碼:

Object.defineProperty(person ,"name",{

    value:"張三瘋"

});

      中的value就表示name屬性的值爲 “張三瘋”。

2)、屬性描述分爲:數據描述符和存取描述符,

            (1)、數據描述符有兩個:value和writable

       (2)、存取描述符:是由一對 getter、setter 函數功能來描述的屬性

3)、共有的描述符:

數據描述符和存取描述均具有以下描述符

Configrable,enumerable

4)、屬性描述符的解釋

Value: 屬性的取值

Writable:屬性是否可以修改

configurable描述屬性是否配置,以及可否刪除

enumerable 描述屬性是否會出現在for in 或者 Object.keys()的遍歷中

get:針對命名訪問器屬性值的獲取

Set:針對命名訪問器屬性值的修改

默認值:

屬性名

默認值

Value

Undefined

Writable

False

configurable

False

enumerable

False

get

Undefined

Set

Undefined

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章