对象采用大括号表示,这导致了一个问题:如果行首是一个大括号,它到底是表达式还是语句?
如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象
属性的操作
属性的读取:
2种方式:1, 点运算符,方括号运算符,其中用方括号运算符时,记得用引号引用,否则就会当成变量处理
属性的查看:Object.keys
判断属性是否存在: in
属性的删除:delete, 返回false只有一种情况,那就是删除不可删除的元素,即便是删除不存在的属性,也会返回true
属性的遍历
for...in
循环有两个使用注意点。
- 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
- 它不仅遍历对象自身的属性,还遍历继承的属性。
var obj = {};
// toString 属性是存在的
obj.toString // toString() { [native code] }
for (var p in obj) {
console.log(p);
} // 没有任何输出
上面代码中,对象obj
继承了toString
属性,该属性不会被for...in
循环遍历到,因为它默认是“不可遍历”的。关于对象属性的可遍历性,参见《标准库》章节中 Object 一章的介绍。
如果继承的属性是可遍历的,那么就会被for...in
循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in
的时候,应该结合使用hasOwnProperty
方法,在循环内部判断一下,某个属性是否为对象自身的属性。
var person = { name: '老张' };
for (var key in person) {
if (person.hasOwnProperty(key)) {
console.log(key);
}
}
// name
with语句(不建议使用)
with
语句的格式如下:
with (对象) {
语句;
}
注意,如果with
区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。
var obj = {};
with (obj) {
p1 = 4;
p2 = 5;
}
obj.p1 // undefined
p1 // 4
上面代码中,对象obj
并没有p1
属性,对p1
赋值等于创造了一个全局变量p1
。正确的写法应该是,先定义对象obj
的属性p1
,然后在with
区块内操作它。
这是因为with
区块没有改变作用域,它的内部依然是当前作用域。这造成了with
语句的一个很大的弊病,就是绑定对象不明确。