javascript 中的 hasOwnProperty & Object.keys 未按预期工作
hasOwnProperty & Object.keys in javascript not working as expected
目的:只继承对象键,不继承被继承的键
两个构造函数:Person 和 Teacher。 Teacher 正在使用原型继承来继承属性。
身高和体重是人传人的两个关键。
据我了解,for ... in 循环遍历对象中的所有键以及继承的键。因此 hasOwnProperty 用于过滤仅在 Teacher 对象中可用的属性。然而,代码输出所有属性,包括它不应该的高度和重量。
/* eslint-disable no-console */
function Person(first, last, age, gender, interests, weight, height) {
this.name = {
first,
last,
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.weight = weight;
this.height = height;
}
Person.prototype.greeting = () => {
console.log(`Hi! I'm ${this.name.first}.`);
};
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}
Teacher.prototype.greeting = () => {
let prefix;
if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
prefix = 'Mr.';
} else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
prefix = 'Mrs.';
} else {
prefix = 'Mx.';
}
console.log(`Hello. My name is ${prefix} ${this.name.last}, and I teach ${this.subject}.`);
};
Teacher.prototype = Object.create(Person.prototype);
Object.defineProperty(Teacher.prototype, 'constructor', {
value: Teacher,
enumerable: false, // so that it does not appear in 'for in' loop
writable: true,
});
const teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
for(var key in teacher1){
if(teacher1.hasOwnProperty(key)){
console.log(key);
}
}
// Output: name, age, gender, interests, weight, height, subject
// weight and height should not be here
name
、age
等 teacher1
上的属性是 自己的属性。它们不是从 teacher1
的原型 (Teacher.prototype
) 或 它的 原型 (Person.prototype
) 继承的。尽管分配给它们的是 Person
,但它们仍然是自己的属性。 Teacher
对 Person
的调用中的 this
是将分配给 teacher1
的对象,因此
this.age = age;
...使 age
成为 teacher1
的 属性。
一旦在对象上创建了 属性,就无法知道创建它的函数(如果有)。
您的代码还有一些其他问题:
您正在将箭头函数分配给 Teacher.prototype.greeting
。不要对将被继承的方法使用箭头函数,this
将不会被正确设置。几个相关问题的答案可能有用:
- What's the meaning of “=>” (an arrow formed from equals & greater than) in JavaScript?
您正在分配给 Teacher.prototype.greeting
,然后稍后完全替换 Teacher.prototype
(Teacher.prototype = Object.create(Person.prototype);
)。所以你不会有 greeting
方法。
如果您替换 Teacher.prototype
上的对象,请务必确保其 constructor
属性 是正确的:
Teacher.prototype = Object.create(Person.prototype);
Teacher.prototype.constructor = Teacher; // <===
但是:因为无论如何你都在使用 ES2015+ 特性(箭头函数,模板文字,...),你可以让这一切变得 much 使用 class
syntax.
更简单
目的:只继承对象键,不继承被继承的键
两个构造函数:Person 和 Teacher。 Teacher 正在使用原型继承来继承属性。
身高和体重是人传人的两个关键。
据我了解,for ... in 循环遍历对象中的所有键以及继承的键。因此 hasOwnProperty 用于过滤仅在 Teacher 对象中可用的属性。然而,代码输出所有属性,包括它不应该的高度和重量。
/* eslint-disable no-console */
function Person(first, last, age, gender, interests, weight, height) {
this.name = {
first,
last,
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.weight = weight;
this.height = height;
}
Person.prototype.greeting = () => {
console.log(`Hi! I'm ${this.name.first}.`);
};
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}
Teacher.prototype.greeting = () => {
let prefix;
if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
prefix = 'Mr.';
} else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
prefix = 'Mrs.';
} else {
prefix = 'Mx.';
}
console.log(`Hello. My name is ${prefix} ${this.name.last}, and I teach ${this.subject}.`);
};
Teacher.prototype = Object.create(Person.prototype);
Object.defineProperty(Teacher.prototype, 'constructor', {
value: Teacher,
enumerable: false, // so that it does not appear in 'for in' loop
writable: true,
});
const teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
for(var key in teacher1){
if(teacher1.hasOwnProperty(key)){
console.log(key);
}
}
// Output: name, age, gender, interests, weight, height, subject
// weight and height should not be here
name
、age
等 teacher1
上的属性是 自己的属性。它们不是从 teacher1
的原型 (Teacher.prototype
) 或 它的 原型 (Person.prototype
) 继承的。尽管分配给它们的是 Person
,但它们仍然是自己的属性。 Teacher
对 Person
的调用中的 this
是将分配给 teacher1
的对象,因此
this.age = age;
...使 age
成为 teacher1
的 属性。
一旦在对象上创建了 属性,就无法知道创建它的函数(如果有)。
您的代码还有一些其他问题:
您正在将箭头函数分配给
Teacher.prototype.greeting
。不要对将被继承的方法使用箭头函数,this
将不会被正确设置。几个相关问题的答案可能有用:- What's the meaning of “=>” (an arrow formed from equals & greater than) in JavaScript?
您正在分配给
Teacher.prototype.greeting
,然后稍后完全替换Teacher.prototype
(Teacher.prototype = Object.create(Person.prototype);
)。所以你不会有greeting
方法。如果您替换
Teacher.prototype
上的对象,请务必确保其constructor
属性 是正确的:Teacher.prototype = Object.create(Person.prototype); Teacher.prototype.constructor = Teacher; // <===
但是:因为无论如何你都在使用 ES2015+ 特性(箭头函数,模板文字,...),你可以让这一切变得 much 使用 class
syntax.