經過Object.defineProperty爲對象設置屬性,並同時規定屬性的屬性(可見性,可配置性,可枚舉性等)函數
備註:若是經過var obj = {} obj.age = 18這種方式設置的屬性,他的可見性,可配置性,可枚舉性等都爲true,至關於默認設置了本篇討論的各類屬性都爲true編碼
語法:Object.defineProperty(obj, prop, descriptor)對象
第一個參數:目標對象
第二個參數:須要定義的屬性或方法的名字。
第三個參數:目標屬性所擁有的特性。(descriptor)ip
descriptor:取值
value:屬性的值
writable:若是爲false,屬性的值就不能被重寫,只能爲只讀了
configurable:總開關,一旦爲false,就不能再設置他的(value,writable,configurable)
enumerable:是否能在for...in循環中遍歷出來或在Object.keys中列舉出來。
get:設置方法
set:獲取方法get
備註:Object.getOwnPropertyDescriptor(obj,"name")查看obj對象name屬性的屬性it
descriptor默認值
var a= {}
Object.defineProperty(a,"b",{
value:123
})
console.log(a.b);//123
只設置了value別的並無設置,它會默認把writable,configurable,enumerable都設置爲falseio
configurable 總開關,第一次設置 false 以後,第二次什麼設置也不行了console
備註:若是是不可配置,能夠把writable由true改成false但不能從false改成true
var a= {}
Object.defineProperty(a,"b",{
configurable:false
})
Object.defineProperty(a,"b",{
configurable:true
})
//error: Uncaught TypeError: Cannot redefine property: btable
writable 若是設置爲fasle,就變成只讀了。。
var a = {};
Object.defineProperty(a, "b", {
value : 123,
writable : false
});
console.log(a.b); // 打印 37
a.b = 25; // 沒有錯誤拋出(在嚴格模式下會拋出)
console.log(a.b); // 打印 37, 賦值不起做用。function
enumerable 定義了對象的屬性是否能夠在 for...in 循環和 Object.keys() 中被枚舉。
var a= {}
Object.defineProperty(a,"b",{
value:3445,
enumerable:true
})
console.log(Object.keys(a)); // 打印["b"]
改成false
var a= {}
Object.defineProperty(a,"b",{
value:3445,
enumerable:false
})
console.log(Object.keys(a));// 打印[]
set和get 賦值 或者 取值的時候會分別觸發 set 和 get 對應的函數
注:1.不能同時設置get和set與wriable或value,就是說想用get和set,就不能用wriable或value中的任何一個
2.經過obj={} 這種形式去定義get/set方法的時候,和這裏不太同樣
a.get/set和函數之間不須要冒號,例如obj={get name(){return "xiaol"}} var a= {} Object.defineProperty(a,"b",{ set:function(newValue){ console.log("你要賦值給我,個人新值是"+newValue) }, get:function(){ console.log("你取個人值") return 2 //注意這裏,我硬編碼返回2 } }) a.b =1 //打印 你要賦值給我,個人新值是1 console.log(a.b) //打印 你取個人值 //打印 2 注意這裏,和個人硬編碼相同的