对象的两种定义形式
文字语法:
var obj = {
//...
}
构造形式:
var obj = new Object()
obj.key = value
对象的内容
对象内部一般存储的是属性的名称,它们就像指针(JavaScript理解成引用更合适),指向这些真正的存储位置。
在对象中, 属性名永远是字符串,其他值作为属性名会被转换为一个字符串。
访问属性的两种方法:
- .操作符
- []操作符
var myObject = {
a: 2
};
myObject.a; // 2
myObject["a"]; // 2
可计算属性名
我们一般通过.访问对象属性,但如果你想通过表达式来计算属性名,那就需要[]了
var prefix = "foo";
var myObject = {
[prefix + "bar"]:"hello",
[prefix + "baz"]: "world"
};
myObject["foobar"]; // hello
myObject["foobaz"]; // world
复制对象
- JSON.parse(JSON.stringify(obj))
深拷贝,但对于null
,undefined
一些特殊情况不适用
- ES6的Object.assign()方法
浅拷贝,第一个参数是目标对象,之后还可以跟一个或多个源对象。
var newObj = Object.assign({}, obj)
- 递归实现深拷贝
属性描述符
从ES5开始,所有的属性都具备了属性描述符。
- writable:决定是否可以修改属性的值。
- configurable:决定属性是否可以配置。
- enumerable:决定属性是否可枚举。
我们可以使用Object.getOwnPropertyDescriptor()
获取对象属性的描述符。
可以使用Object.defineProperty()
修改属性描述符的值。
var myObject = {
a:2
};
Object.getOwnPropertyDescriptor( myObject, "a" );
// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }
var myObject = {};
Object.defineProperty( myObject, "a", {
value: 2,
writable: false, // 不可写!
configurable: true,
enumerable: true
}
);
myObject.a = 3;
myObject.a; // 2
让对象不可变
- 结合
writable: false
和configurable: false
可以创建一个真正的常量属性(不可修改,从新定义或删除)
var myObject = {};
Object.defineProperty( myObject, "FAVORITE_NUMBER", {
value: 42,
writable: false,
configurable: false
}
);
- 禁止扩展
如果你想禁止一个对象添加新属性并且保留已有的属性,可以使用
Object.preventExtensions()
var myObject = {
a:2
};
Object.preventExtensions( myObject );
myObject.b = 3;
myObject.b; // undefined
- 密封Object.seal()
- 冻结Object.freeze()
Getter和Setter
对象默认的[[Put]]和[[Get]]操作分别可以控制属性值的设置和获取。
getter和setter都是隐藏函数,会在获取属性值和设置属性值时自动调用。
var myObject = {
// 给 a 定义一个 getter
get a() {
return 2;
}
};
Object.defineProperty( myObject, // 目标对象
"b", // 属性名
{
// 描述符
// 给 b 设置一个 getter
get: function(){
return this.a * 2
},
// 确保 b 会出现在对象的属性列表中
enumerable: true
}
);
myObject.a; // 2
myObject.b; // 4
这两种定义方法都会在对象中创建一个不包含值的属性,对于这个属性的访问会自动调用一个隐藏函数,它的返回值会被当做属性访问的返回值。
判断对象属性是否存在
- obj.hasOwnProperty()只检查当前对象是否存在该属性,不看原型链。
- in操作符会查看原型链。
对象遍历
for...in
可以用来遍历对象的可枚举属性列表(包括原型链)。