您的位置:首页 > 移动开发 > Objective-C

使用Object.defineProperty重新定义属性时需要注意的一点

2016-11-13 20:56 821 查看
使用Object.defineProperty重新定义属性时需要注意的一点,具体说来:

当一个对象已存在某属性,重新定义该属性(如果允许)时,若未指定属性描述器的enumerable或configurable,则其默认值为原有属性描述器的对应的enumerable或configurable值。

TL;DR?

再次定义一个对象的属性时,新属性描述器中未指定的enumerable或configurable其默认值将由原属性描述器提供,而不再是false。

看来长话短说不了,依旧这么长,那就不废话了,举例说明:

设有一对象foo

var foo={
firstName: "Foo",
lastName: "Bar",
get fullName(){
return this.firstName+" "+this.lastName;
}
};

//#test1
console.log(foo.fullName);
//"Foo Bar"


现需对foo进行升级

实现:

1. 支持middleName;

2. 在JSON.stringify(foo)时属性fullName不被序列化;

Object.defineProperty(foo,"fullName",{
configurable:true,
get: function(){
var fullName=this.firstName;
if(this.middleName)
fullName+=" "+this.middleName;
fullName+=" "+this.lastName;
return fullName;
}
});

//#test2
foo.middleName="Tim";
console.log(foo.fullName);
//"Foo Tim Bar"

//#test3
console.log(JSON.stringify(foo));
//{"firstName":"Foo","lastName":"Bar","fullName":"Foo Tim Bar","middleName":"Tim"}


升级后存在bug

从#test3的输出结果可以看出:JSON.stringify(foo)时属性fullName仍被序列化了。

于是检查fullName的属性描述器

console.log(Object.getOwnPropertyDescriptor(foo,"fullName"));
//{get: function fullName(){...}, set:undefined, enumerable:true, configurable:true}


发现enumerable值仍然是true,未指定应该是false才对呀。

是不是浏览器有bug?

换了个浏览器,亦存在同样问题。

浏览器没有错,机制如此而已

只好显式指定enumerable,打补丁修复现有问题。

(function(){
var descriptor=Object.getOwnPropertyDescriptor(foo,"fullName");
descriptor.enumerable=false;
Object.defineProperty(foo,"fullName",descriptor);
})();

//#test4
console.log(JSON.stringify(foo));
//{"firstName":"Foo","lastName":"Bar","middleName":"Ent"}


总算搞定了,坑爹呀!

所以说,使用Object.defineProperty重新定义属性时需要注意
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript descriptor