У меня есть следующий код:
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, это проходит, почему это так?
где вы используете this внутри функции?
@brk Я устанавливаю foo равным this



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема в следующей строке
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?
this работает по-разному в js, и значение this зависит от сценария. Настройка this просто установит контекст. Необходимо знать, почему нам нужно явно установить this, прежде чем делать это
Возврат объекта из конструктора — не лучшая идея. Это разрушит цель конструктора.\
@MaheerAli, можно ли явно установить this внутри конструктора?
@brk OP не настраивается this. Он просто использует другую переменную, которая будет ссылаться на this. И это нормально, потому что переменная все равно будет экземпляром этого конструктора. Я думаю, что на самом деле не имеет большого значения, использовать ли напрямую this или использовать локальную переменную, которая ссылается на this
вы устанавливаете значение глобальной переменной в определении вашей функции, поэтому, когда вы вызываете ее в первый раз, она изменяет foo на объект класса вместо самого класса