var Counter = function(name) {
this.name = name;
this.data = (function() {
console.log(this.name);
})();
};
var counter = new Counter("some name");
Ожидаемое поведение: напечатать "какое-то имя".
Текущее поведение: ничего не печатается.
Я пытаюсь получить доступ к "данным" внутреннего свойства, как только объект будет создан. Эти "данные" извлекаются с использованием функции, которая зависит от внутреннего имени "имя". Однако, когда вызывается вызванное сразу выражение функции, похоже, что он не может получить доступ к свойству this.name
, поэтому я не могу получить данные сразу после построения объекта.
Я могу заставить его работать, сначала определив эквивалент this
типа:
var Counter = function(name) {
var that = {};
that.name = name;
that.data = (function() {
console.log(that.name);
})();
return that;
};
var counter = new Counter("some name");
Почему это происходит? Как я могу заставить его работать элегантным способом?
this
печально известно в JavaScript для изменения в разных контекстах. this
во внутренней функции является глобальным объектом (window
, если вы запустите его в браузере), а не this
объект в конструкторе.
Существует несколько различных решений, в зависимости от того, какую версию JavaScript вы планируете:
Вы можете передать this
значение, apply
[MDN]:
var Counter = function(name) {
this.name = name;
this.data = (function() {
console.log(this.name);
}).apply(this);
};
var counter = new Counter("some name");
Если вы используете ES6, вы можете использовать функции стрелок, которые автоматически связывают this
значение родительской функции:
var Counter = function(name) {
this.name = name;
this.data = (() => {
console.log(this.name);
})();
};
var counter = new Counter("some name");
Другой вариант, похожий на то, что у вас есть в вашем вопросе, является присвоение this
новым переменным that
. Тогда вы можете ссылаться на that
в дочерней функции.
var Counter = function(name) {
var that = this;
that.name = name;
that.data = (function() {
console.log(that.name);
})();
};
var counter = new Counter("some name");
Это было наиболее распространенное решение до тех пор, пока apply
было введено в ECMAScript 5.
this
имеет другое значение, чем во внешней. Вот почему вам нужно передать значение для этого с apply
или сохранить его в другой переменной, подобной that
.
Проблема в вашем примере была контекстом. При использовании (function(){ } )()
вы используете новый контекст, у которого есть this.name
отличное от свойства имени функции Counter
.
Вы можете использовать функцию стрелки, чтобы контекст мог использоваться внутри вашей функции IIFE.
ПРЕДУПРЕЖДЕНИЕ: Моему растворителю нужна поддержка ECMA2015
aka es6
. Другое совпадение без es6
- использовать ответ @Peter Olson.
Здесь вы можете увидеть таблицу совместимости функции стрелки.
const Counter = function(name) {
this.name = name;
this.data = (() => {
console.log(this.name);
})();
};
const counter = new Counter('some name');
Некоторая хорошая информация выше. Мне также интересно, можете ли вы просто назначить this.data
, а затем сразу же вызвать свою функцию сразу после?
var Counter = function(name) {
this.name = name;
this.data = this.name;
console.log(this.data);
};
var counter = new Counter("some name");
return
.name
или передатьname
в качестве параметра функции?