序言
在JavaScript中,我们通常必须赋值对象的属性。本文讨论二种赋值对象属性的办法,剖析他们之间的差别,并通过一个具体实例来阐述这种差别。
方式1:应用for...in
循环遍历对象属性,并用hasOwnProperty
查验特性:
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
}
}
方式2:直接用for...in
循环遍历对象属性:
for (const key in object) {
const element = object[key];
}
差别
这两种方式的重要区别就是hasOwnProperty
的应用。在第一种方式中,使用Object.hasOwnProperty.call(object, key)
来检测现阶段特性是不是目标本身的特性,而非从原型链中传承的特性。这么做能够确保大家仅解决目标本身的特性。
但在第二种方式中,我们并没有开展这类查验,因此在赋值环节中,我们也会解决目标本身的特性和从原型链中传承的特性。
实例
为了能更好地了解这两种方式之间的差别,使我们通过一个具体的事例来做出说明。
function Person() {}
Person.prototype.sayHello = function() {
console.log("Hello!");
};
const person1 = new Person();
person1.name = "Alice";
person1.age = 30;
// 方式1:应用 for...in 循环系统和 hasOwnProperty 查验
console.log("Method 1:");
for (const key in person1) {
if (Object.hasOwnProperty.call(person1, key)) {
console.log(key, person1[key]);
}
}
// 方式2:直接用 for...in 循环系统
console.log("Method 2:");
for (const key in person1) {
console.log(key, person1[key]);
}
在这样一个实例中,大家创建了一个Person
对象,并向原形上加了一个sayHello
方式。随后,大家创建了一个Person
案例person1
,并为他们加了name
和age
特性。
在我们操作方法1赋值person1
的特性时,导出如下所示:
Method 1:
name Alice
age 30
我们只是解决了person1
本身的特性,没有解决从原型链中传承的特性。
但当大家操作方法2赋值person1
的特性时,导出如下所示:
Method 2:
name Alice
age 30
sayHello [Function: sayHello]
大家解决了person1
本身的特性和从原型链中传承的特性。在这样的情况下,我们不仅解决了name
和age
特性,还解决了从Person.prototype
传承的sayHello
方式。
结果
通过以上实例,我们不难发现这两种方式的差别:在赋值对象属性时,应用hasOwnProperty
查验属性方式仅解决目标本身的特性,而直接用for...in
周而复始的方式会与此同时解决目标本身的特性和在原型链中传承的特性。
实际应用中,假如你只关注目标本身的特性,且不期待解决原型链里的特性,那样操作方法1(for...in
循环系统相互配合hasOwnProperty
查验)是一个最佳的选择。可是,如果你想要与此同时解决目标本身和原型链里的特性,或许你可以直接用方式2(只用for...in
循环系统)。