一、如何编写可以计算的对象的属性名
我们都知道对象的属性访问分两种,键访问(["属性名"])和属性访问(.属性名,遵循标识符的命名规范)
对于动态属性名可以这样
var prefix = "foo" var obj = { [prefix +"name"] : "youyi", [prefix +"age"]: "22" }
(这里可以对比学习一下es6中的symbol)
二、如何给对象的属性添加特性
通过Object.defineProperty()定义对象的属性
1、writable为false,不可给对象属性a赋值
var obj = {} Object.defineProperty(obj, "a", { value: 2, writable: false, configurable: true, enumerable: true }) console.log(obj.a)//2
obj.a = 3
console.log(obj.a)//2
2、configurable为false,属性不能再定义第二次,定义之后会报错;也不能删除属性。
属性不能再定义第二次,定义之后会报错
var obj = {} Object.defineProperty(obj, "a", { value: 2, writable: false, configurable: false, enumerable: true }) obj.a = 3 Object.defineProperty(obj, "a", { value: 2, writable: false, configurable: true, enumerable: true })
不能删除属性
var obj = { } obj.a = 3 console.log("normal:", obj.a) delete obj.a console.log("normal:",obj.a) Object.defineProperty(obj, "a", { value: 2, writable: false, configurable: false, enumerable: true }) console.log(obj.a) delete obj.a console.log(obj.a)
输出:
normal: 3
normal: undefined
2
2
3、enumerable为false,属性不会出现在枚举中
什么是可枚举?
对象属性能出现在对象的遍历中就是可枚举。
如何判断属性是否可以枚举?
obj.propertyIsEnumerable("属性名")
如何获取所有可枚举属性?
Object.key(obj)(注意:和getOwnPropertyNames()不同,后者会获取到对象中的所有属性,两者共同点是只查找对象直接包含的属性,不查找原型链上的)
四、创建不可变性的对象
1、writable和configurable都设置为false
2、Object.preventExtensions禁止对象的扩展,不能再添加新的属性
var obj = {} obj.a = 2 Object.preventExtensions(obj) obj.b = 3 obj.b//undefined
3、Object.seal()密封对象,调用Object.preventExtensions,并且将所有属性configurable设置为false。(不可添加新属性,也不能重新配置或
删除现有任何属性)
4、Object.freeze()冻结对象,在Obect.seal()的基础上,将所有数据访问属性writable设置为false。(啥都干不了了)
五、对象中的[[Get]]、[[Put]]、Getter和Setter
当给一个对象设置属性时,会触发[[Put]];
当读取一个对象中的属性时,会触发[[Set]]
创建访问属性符(当给属性定义getter、setter或两者都有时):
var obj = { get a() { return 2 } } Object.defineProperty(obj, "b", { get: function() { return this.a*2 }, enumerable: true })
//obj.a //2
//obj.b //4
属性定义get方法时,赋值操作会无效
var obj = { get a() { return 2 } } obj.a = 3 obj.a //2
六、判断对象属性是否存在
判断对象中是否存在某个属性的两种方式:in和hasOwnProperty,
两者的区别是in会遍历到对象的原型链上,hasOwnProperty只会在对象中查找,不会查找至原型链。
需要注意的是,对于用Object.create(null)创建的空对象和{}不同,前者创建的空对象没有prototype属性
var t = Object.create(null); t.hasOwnProperty("a") //Uncaught TypeError: t.hasOwnProperty is not a function var t = {}; t.hasOwnProperty("a") //false