Конструктор терпит неудачу во второй раз, но не в первый

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

var foo = function () {
    foo = this;
    foo.boo = function () {
        console.info("boo");
    }
}

var bar = new foo().boo();
var baz = new foo().boo();

Этот код выполняет первое создание экземпляра foo, но завершается ошибкой при втором выводе:

boo
/Users/BaranSkistad/Code/example.js:9
var baz = new foo().boo();
          ^

TypeError: foo is not a constructor
    at Object.<anonymous> (/Users/BaranSkistad/Code/example.js:9:11)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)

    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:578:3

Почему этот скрипт не работает? Я знаю, что это как-то связано с установкой foo на this в строке 2, а не просто с использованием this, но почему это проблематично?

var foo = function () {
    self = this;
    self.boo = function () {
        console.info("boo");
    }
}

var bar = new foo().boo();
var baz = new foo().boo();

Если я устанавливаю self равным this, это проходит, почему это так?

вы устанавливаете значение глобальной переменной в определении вашей функции, поэтому, когда вы вызываете ее в первый раз, она изменяет foo на объект класса вместо самого класса

Aurangzeb 10.06.2019 16:02

где вы используете this внутри функции?

brk 10.06.2019 16:39

@brk Я устанавливаю foo равным this

baranskistad 10.06.2019 16:52
Поведение ключевого слова "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) для оценки ваших знаний,...
1
3
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Проблема в следующей строке

foo = this;

В приведенной выше строке отсутствует объявление переменной. Таким образом, foo будет ссылаться на глобальную переменную foo, которая является конструктором. Когда вы вызываете функцию в первый раз, строка выполняется, и foo изменяется на this(экземпляр foo)

Во втором случае код также создает глобальную переменную self, которая будет равна this. Но в этом случае он не изменит конструктор, потому что имена разные.

Решение этой проблемы состоит в том, чтобы сделать foo локальной переменной с помощью let(или const/var).

var foo = function () {
    let foo = this;
    foo.boo = function () {
        console.info("boo");
    }
}

var bar = new foo().boo();
var baz = new foo().boo();

Хотя вы уже получили ответ, но вы не можете явно установить this. Если вы console.info внутри foo функции, она зарегистрирует object. Вместо этого вы можете просто return создать object, у которого будут все внутренние функции.

var foo = function() {
  return {
    testVal: 5,
    boo: function() {
      console.info("boo ", this.testVal);
    }
  }
}

var bar = new foo().boo();
var baz = new foo().boo();

Есть ли случай, когда вы не можете явно установить this?

baranskistad 10.06.2019 17:11
this работает по-разному в js, и значение this зависит от сценария. Настройка this просто установит контекст. Необходимо знать, почему нам нужно явно установить this, прежде чем делать это
brk 10.06.2019 17:16

Возврат объекта из конструктора — не лучшая идея. Это разрушит цель конструктора.\

Maheer Ali 10.06.2019 17:19

@MaheerAli, можно ли явно установить this внутри конструктора?

brk 10.06.2019 17:23

@brk OP не настраивается this. Он просто использует другую переменную, которая будет ссылаться на this. И это нормально, потому что переменная все равно будет экземпляром этого конструктора. Я думаю, что на самом деле не имеет большого значения, использовать ли напрямую this или использовать локальную переменную, которая ссылается на this

Maheer Ali 10.06.2019 17:50

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