Проверка instanceof с классом

У меня есть следующий код:

function Complex(real, imaginary) {
    let c = Object.create(Complex.methods);
    [c.real, c.imaginary] = [real, imaginary];
    return c;
}

Complex.methods = {
    toString() {return `${this.real}+${this.imaginary}i`},
    add(other) {
        if (!(other instanceof Complex)) throw new Error("Only supports complex-only addition");
        return Complex(this.real+other.real, this.imaginary+other.imaginary);
    }
}
let c1 = Complex(2,0);
let c2 = Complex(3,4);
console.info(c1.add(c2) + "");
// "Uncaught Error: Only supports complex-only addition",

Это происходит потому, что c1 instanceof Complex возвращается false. Почему он возвращает ложь?

Сравните это с использованием ключевого слова class:

class CX {
    toString() {return "xxx"}
}
let c1 = new CX();
console.info(c1 + "", c1 instanceof CX);
// xxx true

Но все же любопытно, почему первый не распознает оператор instanceof.

Complex — это фабричная функция, которая создает объект через Object.create. Прототип этого недавно созданного объекта — это объект, который был прибит непосредственно к Complex в качестве свойства methods этой функции. Таким образом, поскольку Complex не является функцией-конструктором (вызывается через new), экземпляров Complex также нет.
Peter Seliger 09.04.2022 02:01

@PeterSeliger хорошо, если бы я вызывал его как let c1 = new Complex(2,0); пусть c2 = Complex(3,4);` позволит ли это мне использовать instanceof ? Или как я увижу, что c2 был создан с помощью фабрики Complex()?

David542 09.04.2022 02:03
other.constructor.name возвращает Объект, а c1.constructor.name возвращает клиентский опыт. Попробуйте отладить его таким образом.
Reza Saadati 09.04.2022 02:08

@RezaSaadati Понятно, хотя я не очень понимаю, не могли бы вы опубликовать ответ с некоторыми подробностями?

David542 09.04.2022 02:24

Вы понимаете как instanceof работает? Непонятно, почему вы ожидаете, что объект, который наследуется от Complex.methods, а не Complex.prototype, будет instanceof Complex.

Bergi 09.04.2022 05:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

OP либо выбирает классический (старый добрый) подход к функции конструктора...

function Complex(real, imaginary) {
  Object.assign(this, { real, imaginary });
}
Complex.prototype.toString = function toString () {
  return `${this.real} + ${this.imaginary}i`
};
Complex.prototype.add = function add (other) {
  if (!(other instanceof Complex)) {
    throw new Error("Only supports complex-only addition");
  }
  return new Complex(
    this.real + other.real,
    this.imaginary + other.imaginary
  );
};
let c1 = new Complex(2,0);
let c2 = new Complex(3,4);

console.info(c1.add(c2) + "");
.as-console-wrapper { min-height: 100%!important; top: 0; }

... или подход, основанный на классах...

class Complex {
  constructor(real, imaginary) {
    Object.assign(this, { real, imaginary });
  }
  toString () {
    return `${this.real} + ${this.imaginary}i`
  }
  add (other) {
    if (!(other instanceof Complex)) {
      throw new Error("Only supports complex-only addition");
    }
    return new Complex(
      this.real + other.real,
      this.imaginary + other.imaginary
    );
  }
}
let c1 = new Complex(2,0);
let c2 = new Complex(3,4);

console.info(c1.add(c2) + "");
.as-console-wrapper { min-height: 100%!important; top: 0; }

Спасибо за это. Только один вопрос: почему вы используете Object.assign(...), а не Object.create(...) выше?

David542 09.04.2022 02:28

Object.assign(this, { real, imaginary }); то же самое, что и this.real=real; this.imaginary=imaginary, и это просто ярлык?

David542 09.04.2022 02:43
Object.create сам по себе бесполезен, если речь идет об экземплярах и операторе instanceof. И выбор Object.assign просто короче, если речь идет о назначении множества параметров конструктора в качестве свойств экземпляра... constructor(foo, bar, baz, biz, buz) { Object.assign(this, { foo, bar, baz, biz, buz }); }... проще написать, чем... constructor(foo, bar, baz, biz, buz) { this.foo = foo; this.bar = bar; this.baz = baz; this.biz = biz; this.buz = buz; }
Peter Seliger 09.04.2022 02:45

Другие вопросы по теме