hasOwnProperty & Object.keys в JavaScript не работает должным образом - PullRequest
0 голосов
/ 27 ноября 2018

Цель: наследовать только ключи объекта, а не те, которые унаследованы

Два конструктора: Персона и Учитель.Учитель наследует свойства, используя прототип наследования.

Рост и вес - это два ключа, унаследованных от человека к учителю.

Насколько я понимаю, ... 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 голосов
/ 27 ноября 2018

Свойства name, age и т. Д., Свойства teacher1 являются собственностью .Они не наследуются от прототипа teacher1 (Teacher.prototype) или его прототипа (Person.prototype).Хотя Person назначает их, они все еще являются собственными свойствами.this при вызове Person из Teacher - это объект, который будет присвоен teacher1, поэтому

this.age = age;

... делает age собственным свойством teacher1.

После того, как свойство было создано для объекта, невозможно узнать, какая функция (если есть) его создала.


Есть несколько других проблем с вашим кодом:

  1. Вы назначаете функцию стрелки для Teacher.prototype.greeting.Не используйте функции стрелок для методов, которые будут наследоваться, this не будет установлен правильно.Пара связанных вопросов, ответы на которые могут быть полезны:

  2. Вы назначаете Teacher.prototype.greeting, а затем полностью заменив Teacher.prototype (Teacher.prototype = Object.create(Person.prototype);).Таким образом, у вас не будет метода greeting.

  3. Если вы замените объект на Teacher.prototype таким, какой вы есть, важно сделатьубедитесь, что его свойство constructor указано правильно:

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

Но : поскольку вы все равно используете функции ES2015 + (функции стрелок, литералы шаблонов, ...), вы можете сделать все это намного проще, используя class синтаксис .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...