Подтвердить что ты не робот

'this' функция внутри функции прототипа

У меня в основном есть объект, расширенный функцией через его прототип. Внутри этой функции существует еще одна функция, однако при использовании this в этой вложенной функции она, похоже, не ссылается на объект, а на функцию.

Например,

var sampleObject = function() {
 this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }
 return nested();
}

var test = new sampleObject();

window.alert(test.getFoo()); // undefined

this.foo не ссылается на значение 123, но имеет значение undefined, так как это относится к вложенной функции, в которой нет foo. Как я могу получить доступ к значению 123 из вложенной функции?

Спасибо.

4b9b3361

Ответ 1

sampleObject.prototype.getFoo = function() {
 var me = this;
 var nested = function() {
  return me.foo;
 }
 return nested();
}

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

Ответ 2

Общей задачей для этого является использование замыкания

sampleObject.prototype.getFoo = function() {
  var _this = this; 
  var nested = function() {
    return _this.foo;
   }
   return nested();
}

Некоторые библиотеки добавляют методы для автоматизации этого

Ответ 3

В вашем примере "this" ссылается на объект окна, потому что вы не указали другой контекст, когда вы вызываете вложенную функцию, и вы получаете undefind, потому что window.foo - undefined.

Вы можете исправить это тремя способами.

1 - Используйте переменную, чтобы сохранить внешний вид этого - наиболее используемый метод

sampleObject.prototype.getFoo = function() {
 var _this = this;
 var nested = function() {
  return _this.foo;
 }
 return nested();
}

2 - Используйте метод связывания, связывающий внешний "this" с внутренним

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }.bind(this);
 return nested();
}

3 - Используйте метод вызова, который может передать контекст функции

SampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 };
 return nested.call(this);
}

Ответ 4

Помимо объявления его var _this = this, я также вижу коды, выполняющие var that = this или var self = this.

Знание области видимости переменной важно, так как это может привести к неожиданному результату.

Ответ 5

Это старый вопрос, но я даю другое решение для полноты. Другой подход включает привязку функций.

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }
 return nested.bind(this)();
}

Ответ 6

Это известная бородавка на JavaScript. Обычным шаблоном является присвоение этой переменной другой переменной (часто само) во внешней функции, а затем доступ к себе из внутренней функции. Это работает.

Ответ 7

TL;DR

Используйте функции стрелок. Они доступны с ECMAScript 6:

var sampleObject = function() {
  this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
  var nested = () => { // Changed this line.
    return this.foo;
  }
  return nested();
}

var test = new sampleObject();

window.alert(test.getFoo());