javascript中的hasOwnProperty&Object.keys无法正常工作

时间:2018-11-27 17:06:07

标签: javascript for-in-loop hasownproperty

目的:仅继承对象键,而不继承

两个构造函数:Person和Teacher。教师正在使用原型继承来继承属性。

身高和体重是人与老师之间继承的两个关键。

据我了解,... 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

1 个答案:

答案 0 :(得分:4)

name 上的ageteacher1等属性是自己的属性。它们不是从teacher1的原型(Teacher.prototype)或原型(Person.prototype)继承而来。尽管是Person为其分配的,但它们仍然是自己的属性。 thisPerson的调用中的Teacher是将分配给teacher1的对象,所以

this.age = age;

...使age成为teacher1的财产。

一旦在对象上创建了属性,就无法知道是由哪个函数创建的。


您的代码还有其他一些问题:

  1. 您正在为Teacher.prototype.greeting分配箭头功能。不要将箭头函数用于将要继承的方法,this的设置将不正确。几个相关的问题,可能会有用的答案:

  2. 您要分配给Teacher.prototype.greeting,然后再完全替换Teacher.prototypeTeacher.prototype = Object.create(Person.prototype);)。因此,您将没有greeting方法。

  3. 如果您以Teacher.prototype的方式替换对象,请务必确保其constructor属性正确:

    Teacher.prototype = Object.create(Person.prototype);
    Teacher.prototype.constructor = Teacher; // <===
    

但是:由于您仍在使用ES2015 +功能(箭头功能,模板文字等),因此,您可以使用{{ 3}}。