1 delete attributes: delete command
delete
Command is used to delete the object attributes, delete successful return true
.
var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
obj.p // undefined
Object.keys(obj) // []
The above code, the delete
command to remove the object obj
's p
attributes. After deleting, and then read the p
property will be returned undefined
,
And Object.keys
the return value of the method is no longer include this property.
Note that deleting a property that does not exist, delete
no error, and returns true
.
var obj = {};
delete obj.p // true
In the above code, the object obj
is not p
property, but the delete
command still returns true
.
Therefore, not according to delete
the results of the command, found a property is there.
Only one case, delete
the command will return false
, and that is the property exists, and may not be deleted
var obj = Object.defineProperty({}, 'p', {
value: 123,
configurable: false
});
obj.p // 123
delete obj.p // false
Among the above code, the object obj
's p
attributes can not be deleted, so the delete
command returnsfalse
(On Object.defineProperty
presentation methods, see "Standard Library" Object object chapter).
Also, note that the delete
command can only remove property of the object itself,
You can not delete inherited property (see "Object-Oriented Programming" section on inheritance).
var obj = {};
delete obj.toString // true
obj.toString // function toString() { [native code] }
The above code, toString
the object of obj
inherited properties, although the delete
command returns true
,
But the property has not been deleted, still exists. This example also illustrates that even delete
return true
, the property is still possible to read the value.
1.1 property exists: in operator
in
Operator for checking whether the object contains an attribute (note, check that the keys are not the key),
If you include returns true
, otherwise it returns false
. It's left is a string that represents the attribute name, the right is an object
var obj = { p: 1 };
'p' in obj // true
'toString' in obj // true
in
Operator is a problem that it is not identify which attributes of the object itself, which property is inherited.
Like the above code, the object obj
itself is not toString
property, but the in
operator returns true
, because this property is inherited.
In this case, you can use the object's hasOwnProperty
method to determine what, whether the object's own properties.
var obj = {};
if ('toString' in obj) {
console.log(obj.hasOwnProperty('toString')) // false
}
1.2 traversing the property: for ... in loop
for...in
Loop is used to iterate all attributes of an object.
{A obj = var:. 1, B: 2, C:. 3};
for (var in I obj) {
the console.log ( 'key name:', I);
the console.log ( 'key:', obj [ I]);
}
// keys: A
@ key: 1
// key name: B
@ keys: 2
@ keys: C
@ keys: 3
for...in
Note the use of the cycle there are two points.
- It is the object traversing all traverse (Enumerable) properties, properties not traversable skipped.
- It is not only traverse the object's own properties, but also traverse the inheritance of property.
举例来说,对象都继承了toString
属性,但是for...in
循环不会遍历到这个属性。
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
2 with 语句
with
语句的格式如下:
with (对象) {
语句;
}
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
// 例一
var obj = {
p1: 1,
p2: 2,
};
with (obj) {
p1 = 4;
p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;
// 例二
with (document.links[0]){
console.log(href);
console.log(title);
console.log(style);
}
// 等同于
console.log(document.links[0].href);
console.log(document.links[0].title);
console.log(document.links[0].style);
注意,如果with
区块内部有变量的赋值操作,必须是当前对象已经存在的属性,
否则会创造一个当前作用域的全局变量。
var obj = {};
with (obj) {
p1 = 4;
p2 = 5;
}
obj.p1 // undefined
p1 // 4
上面代码中,对象obj
并没有p1
属性,对p1
赋值等于创造了一个全局变量p1
。
正确的写法应该是,先定义对象obj
的属性p1
,然后在with
区块内操作它。
这是因为with
区块没有改变作用域,它的内部依然是当前作用域。
这造成了with
语句的一个很大的弊病,就是绑定对象不明确。
with (obj) {
console.log(x);
}
单纯从上面的代码块,根本无法判断x
到底是全局变量,还是对象obj
的一个属性。
这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,
只能留到运行时判断,这就拖慢了运行速度。
因此,建议不要使用with
语句,可以考虑用一个临时变量代替with
。
with(obj1.obj2.obj3) {
console.log(p1 + p2);
}
// 可以写成
var temp = obj1.obj2.obj3;
console.log(temp.p1 + temp.p2);
文章内容转自 阮一峰老师 JavaScript教程 https://wangdoc.com/javascript/index.html