ECMA5弄了一个新东西, 就是用户可以通过Object.defineProperty配置属性的可写,可配置,可枚举, 让我们开发者可以定义一些属性,这些属性有点像native的赶脚
比如,我们平常定义一个对象这样子就可以了;
var obj0 = {
name : "nono"
};
我们也可以用新的方式,Object的属性设置方法defineProperty设置属性, 如果用户没有传enumberable, configurable, writable的值, 默认是false, 也就是说默认是无法枚举,无法配置, 无法可写的:
var obj1 = {};
Object.defineProperty(obj1, "name",{
writable : false,
configurable : false,
enumerable : false,
value : "nono"
});
writable
这个配置是不可写的,所以把对象obj1的name重新定义无效,(在ecma的严格模式报错);
<html>
<body>
<script>
var obj1 = {};
Object.defineProperty(obj1, "name",{
writable : false,
value : "nono"
});
console.log("我的名字是: "+ obj1.name);
//重新定义名字;
obj1.name = "qihao";
//删除名字
delete obj1.name;
console.log("我的新名字是: "+ obj1.name);
</script>
</body>
</html>
这个是打印出来的结果:
,声明我们删除和重新定义名字的代码没生效, 因为writable是false;
我们把元素的writable的配置从true改到false,再改到true,会报错
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj1 = {};
Object.defineProperty(obj1, "favor",{
writable : true,
value : "poppin"
});
Object.defineProperty(obj1, "favor",{
writable : false,
value : "readBook"
});
try{
//如果重新定义可写属性从false到true会报错;
Object.defineProperty(obj1, "favor",{
writable : true,
value : "poppin"
});
}catch(e) {
console.log( "definedProperty error" + e );
}
</script>
</body>
</html>
,因为默认的configurable是false, 所以重新配置writable报错了;
configurable
现在的cofigurable派上用场了:
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj1 = {};
Object.defineProperty(obj1, "favor",{
writable : true,
configurable : true,
value : "poppin"
});
console.log( obj1.favor );
Object.defineProperty(obj1, "favor",{
writable : false,
configurable : true,
value : "readBook"
});
console.log( obj1.favor );
try{
//因为configurable为true了,所以重新定义favor的writable不会报错;
Object.defineProperty(obj1, "favor",{
writable : true,
value : "poppin"
});
}catch(e) {
console.log( "definedProperty error" + e );
};
console.log( obj1.favor );
</script>
</body>
</html>
结果是:
也就是我们通过配置configurable为true, 那么随时要更改enumerable,value, writable的配置为false或者true都没有问题;
enumerable
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj1 = {};
Object.defineProperty(obj1, "favor",{
enumerable : false,
value : "poppin"
});
Object.defineProperty(obj1, "age", {
value : 27
});
Object.defineProperty(obj1, "weight",{
"value" : 64,
enumerable : true
});
for(var p in obj1)console.log( p );
</script>
</body>
</html>
就输出了weight这个属性
, favor和age这两个属性没有枚举到;
Object.getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor可以获取详细的描述, 不过还是没有native的牛逼....;
Object.defineProperties
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj1 = {};
Object.defineProperties(obj1,{
x : {value : "x"},
y : {enumerable : true},
z : {writable : true}
});
for(var p in obj1)console.log( p );
</script>
</body>
</html>
通过defineProperties可以一次定义多个属性, 方便快捷
访问器属性,get, set
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj = {};
Object.defineProperty(obj, "name", {
set : function(name) {
this._name = name+" afterfix";
},
get : function() {
return "prefix " + this._name;
}
});
obj.name = "nnnn";
console.log( obj.name );
</script>
</body>
</html>
old get,set ,非标准的Getter,Setter方法
在ecma5标准未被采纳之前,大多数js解释引擎实现了非标准的get,set方法, chrome下现在还有这些方法:
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var obj = {};
obj.__defineGetter__("g", function() {
return this._g+"__";
});
obj.__defineSetter__("g", function(arg) {
this._g = arg;
});
</script>
</body>
</html>
输出结果:
天道酬勤