javaScript中的Object類型

屬性描述符

JavaScript提供了一個內部數據結構,用於描述對象的值,控制其行爲,例如該屬性是否可寫、是否可配置、是否可修改以及是否可枚舉等。這個內部數據結構被稱爲‘屬性描述符’。
每一個屬性都有本身對應的屬性描述符,保存該屬性的元信息。前端

{
    value:'前端',
    writable:false,
    enumerable:true,
    configurable:false,
    get:undefined,
    set:undefined
}

對象裏目前存在的屬性描述符有兩種主要形式:數據描述符和存取描述符數據結構

數據描述符

數據描述符是一個具備值的屬性,該值多是可寫的,也可能不是可寫的。數據描述符具備如下可選鍵值:函數

  • value:該屬性對應的值,能夠是任何有效的JavaScript值(數值,對象,函數等)。默認爲undefined
  • writable:當該屬性的writable爲true時,value才能被賦值運算符改變。默認爲false
  • configurable:當該屬性的configurable爲true時,該屬性描述符纔可以被改變,同時該屬性也能從對應的對象上被刪除,默認爲false
  • enumerable:當該屬性的enumerable爲true時,該屬性纔可以出如今對象的枚舉屬性中,默認爲false

存取描述符

存取描述符是由getter-setter函數對描述的屬性。存取描述符具備如下可選鍵值:this

  • get:給屬性提供getter的方法,若是沒有getter則爲undefined。當訪問該屬性時,該方法會被執行,方法執行時沒有參數傳入,可是會傳入this對象
  • set:給屬性提供setter的方法,若是沒有setter則爲undefined。當屬性值修改時,觸發執行該方法。該方法將接受惟一參數,即該屬性新的參數值。
  • configurable:當該屬性的configurable爲true時,該屬性描述符纔可以被改變,同時該屬性也能從對應的對象上被刪除,默認爲false
  • enumerable:當該屬性的enumerable爲true時,該屬性纔可以出如今對象的枚舉屬性中,默認爲false。

獲取屬性描述符

Object.getOwnPropertyDescriptor()方法返回指定對象上一個自有屬性對應的屬性描述符。code

Object.getOwnPropertyDescriptor(obj,prop)
  • obj:須要查找的目標對象
  • prop:目標對象內屬性名稱(String類型)
  • 返回值:若是指定的屬性存在於對象上,則返回其屬性描述符對象,不然返回undefined
var obj={}
obj.attr='前端';

console.log(Object.getOwnPropertyDescriptor(obj,'attr'));

設置屬性描述符

1.Object.defineProperty()方法爲對象定義新屬性或修改現有屬性,並返回該對象對象

Object.defineProperty(obj,prop,descriptor);
  • obj:要在其上定義屬性的對象
  • prop:要定義或修改的屬性的名稱
  • descriptor:將傳遞給函數的對象
  • 返回值:被傳遞給函數的對象

2.Object.defineProperties()方法爲對象定義一個或多個新屬性或修改現有屬性,並返回該對象ip

Object.defineProperties(obj,props)
  • obj:要在其上定義屬性的對象
  • props:要定義其可枚舉屬性或修改的屬性描述符的對象
  • 返回值:被傳遞給函數的對象

屬性描述符的可選鍵值

1.value:表示目標屬性對應的值。能夠是任何有效的JavaScript值(數值,對象,函數等)。默認爲undefinedget

var obj={};
obj.name='張三';

var attr=Object.getOwnPropertyDescriptor(obj,'name');
console.log(attr.value);

Object.defineProperty(obj,'name',{value:'李四'});
console.log(obj.name);

2.writable:Boolean值,表示目標屬性的值是否能夠被修改。當該屬性的writable爲true時,value才能被賦值運算符改變。默認爲falsestring

var obj={};
Object.defineProperty(obj,'attr',{
       value:'前端',
       writable:false
});
console.log(obj.attr);
obj.attr=100;
console.log(obj.attr);

3.configurable:Boolean值,表示目標屬性的描述符是否能夠修改。當該屬性的configurable爲true時,該屬性描述符纔可以被改變,同時該屬性也能從對應的對象上被刪除。默認爲falseit

var obj=Object.definePropety({},'attr',{
    value:'大前端',
    configurable:false
});

Object.definePropety(obj,'attr',{value:100});
Object.definePropety(obj,'attr',{writable:true});
Object.definePropety(obj,'attr',{enumerable:true});
Object.definePropety(obj,'attr',{configurable:true});

4.enumerable:Boolean值,表示目標屬性是否可遍歷。當該屬性的enumerable爲true時,該屬性纔可以出如今對象的枚舉屬性中。默認爲false
若是對象的屬性的enumerable的值爲false,如下三種操做取不到該屬性:

  • for...in語句
  • Object.keys()方法
  • JSON.stringify()方法
var obj={};
Object.defineProperty(obj,'attr',{value:'前端',enumerable:false});
for(var key in obj){console.log(key);}
console.log(Object.keys(obj));
console.log(JSON.stringify(obj));

屬性描述符的存取器

對象的屬性除了能夠直接定義之外,還可使用存取器進行定義。其中setter爲存值函數,使用屬性描述符中的set;getter爲取值函數,使用屬性描述符中的get

var obj=Object.defineProperty({},'attr',{
    get:function(){
        return '前端';
    },
    set:function(){
        console.log('setter:'+value);
    }
});

console.log(obj.attr);
obj.attr=100;

JavaScript中除了上述存取器的寫法以外,還提供瞭如下寫法:

var obj={
    get attr(){
        return '前端';
    },
    set attr(value){
        console.log('setter:'+value);
    }
}

console.log(obj.attr);
obj.attr=100;

防篡改

定義的對象默認在任什麼時候候、任何位置,不管有意義的仍是無心義的均可以修改對象的屬性或方法。
而這些篡改可能會影響對象的內置屬性或方法,從而致使對象的正常功能可能沒法使用。
1.禁止擴展:禁止爲對象擴展新的屬性或方法

var obj={};
Object.preventExtensions(obj);
obj.attr='前端';
console.log(Object.isExtensible(obj));
console.log(obj.attr);

2.密封對象:禁止擴展新的屬性或方法,禁止配置現有的屬性或方法的描述符,僅容許讀寫屬性的值

var sealed={};
Object.seal(sealed);
Object.isSealed(sealed);

Object.isExtensible(sealed);

3.凍結對象:禁止對對象執行任何修改操做

var frozen={1:81};
Object.isFrozen(frozen);
Object.freeze(frozen);
Object.isFrozen(frozen);

Object.isSealed(frozen);
Object.isExtensible(frozen);
相關文章
相關標籤/搜索