Почему myObject.function () выбрасывает ошибку «не является функцией»?(пытаясь научиться функциональной реализации) - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь создать класс, используя функцию и предоставив ей некоторые реквизиты и метод. Если я делаю то же самое в C # на основе классов и вызываю mothod, это будет работать нормально, но в JS выдает ошибку. У меня вопрос, почему он ведет себя по-другому.

фрагмент кода:

function Animal (name) {
    let animal = {}
    animal.name = name;
    animal.eat = function (){ 
        console.log(`${this.name} is eating`)
    }
}

let myAnimal = new Animal('dog');
console.log(myAnimal.eat()); //Uncaught TypeError: myAnimal.eat is not a function at proto.js:11

Ответы [ 3 ]

3 голосов
/ 14 июня 2019

Это был бы прототипический способ достижения этого в JavaScript:

function Animal(name) {
  this.name = name;
}

Animal.prototype.eat = function() {
  console.log(`${this.name} is eating`)
}

new Animal('Pooch').eat();

Или с введением классов (начиная с ECMAScript 2015):

class Animal {
  constructor(name) {
    this.name = name;
  }

  eat() {
    console.log(`${this.name} is eating`)
  }
}

new Animal('Pooch').eat();
1 голос
/ 14 июня 2019

хорошо, если Animal будет выступать в качестве конструктора вашего сорта класса , то вам нужно будет написать его как правильный конструктор, то есть отбросить бит let animal = {} и просто установитьсвойства this:

function Animal (name) {
    this.name = name;
    this.eat = function (){ 
        console.log(`${this.name} is eating`)
    }
}

let myAnimal = new Animal('dog');
myAnimal.eat();

Теперь у этого подхода есть обратная сторона: создание новой функции eat() для каждого экземпляра Animal вместо привязки существующей функции eat() к каждому экземпляру, чтоэто то, что обычно происходит с классами.что вы можете достичь этим:

function Animal (name) {
    this.name = name;
}

Animal.prototype.eat = function (){ 
  console.log(`${this.name} is eating`)
}

let myAnimal = new Animal('dog');
myAnimal.eat();

, который на самом деле является правильным способом, которым люди использовали для определения классов в javascript до введения class.

однако вы также можете отбросить целое классоподобная концепция, и просто есть функция Animal(), которая выдает объект с желаемыми свойствами:

function Animal (name) {
    let animal = {};
    animal.name = name;
    animal.eat = function (){ 
        console.log(`${this.name} is eating`)
    }
    
    return animal;
}

let myAnimal = Animal('dog');
myAnimal.eat();

обратите внимание, что в этом подходе вместо let myAnimal = new Animal('dog') используется let myAnimal = Animal('dog'), поскольку Animal() больше не является конструктором.

напоминание : это объяснение того, как вы можете создавать экземпляры объектов с помощью функции, и никоим образом не рекомендуемый способ определения классов в javascript.в более старых средах подход prototype является рекомендуемым, для более новых сред просто используйте class.

1 голос
/ 14 июня 2019

Перейти с подходом Робби выше. Для исправления вашего кода вы пропустили оператор return animal;:)

function Animal (name) {
      let animal = {}
      animal.name = name;
      animal.eat = function (){ 
        console.log(`${this.name} is eating`)
       }
      return animal;
     }

    let myAnimal = new Animal('dog');
    console.log(myAnimal.eat());
...