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

Значение "this" в node.js модулях и функциях

У меня есть файл JavaScript, который загружается require.

// loaded by require()

var a = this; // "this" is an empty object
this.anObject = {name:"An object"};

var aFunction = function() {
    var innerThis = this; // "this" is node global object
};

aFunction();

(function(anyParameter){
    console.log(anyParameter.anObject);
})(
    this // "this" is same having anObject. Not "global"
);

Мой вопрос: this в var a = this; - пустой объект, тогда как операторы this в функциях являются тенями глобального объекта node.js. Я знаю, что ключевое слово this отличается от функций, но я не мог понять, почему первая this не равна глобальным, а this в функциях равна глобальным.

Как node.js вводят global в this в области видимости функций и почему он не вводит его в область видимости модуля?

4b9b3361

Ответ 1

Вот несколько фундаментальных фактов, которые вы должны понять, чтобы прояснить ситуацию:

  • В коде верхнего уровня в модуле Node this эквивалентен module.exports. Это пустой объект, который вы видите.

  • Когда вы используете this внутри функции, значение this определяется заново перед каждым исполнением функции, а ее значение определено как выполняется функция. Это означает, что две вызовы одного и того же функционального объекта могут иметь разные значения this, если механизмы вызова различны (например, aFunction() vs. aFunction.call(newThis) vs. emitter.addEventListener("someEvent", aFunction); и т.д.). В вашем случае aFunction() в нестрогом режиме запускается функция с this, установленным для глобального объекта.

  • Когда файлы JavaScript являются require d как модули Node, механизм Node запускает код модуля внутри функции-обертки. Эта функция обматывания модулей вызывается с помощью this, установленного на module.exports. (Вспомните, что выше, функция может быть запущена со значением this)

Таким образом, вы получаете разные значения this, потому что каждый this находится внутри другой функции: первая находится внутри функции Node -created module-wrapper, а вторая находится внутри aFunction.

Ответ 2

Чтобы понять это, вам нужно понять, что Node.js фактически переносит ваш код модуля в функцию, например,

(function (exports, require, module, __filename, __dirname) {
    var test = function(){
        console.log('From test: '  + this);
    };
    console.log(this);
    test();
});

Подробное объяснение можно найти в этом ответе.


Теперь эта завернутая функция фактически вызывается как это

var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);

Итак, this, на уровне модуля, на самом деле является объектом exports.

Вы можете подтвердить, что вот так

console.log(this, this === module.exports);
// {} true

Ответ 3

Это потому, что глобальный объект по умолчанию в модуле Node.js является объектом exports, и вы вызываете test(), который не указывает this. В традиционном JS this указывает на глобальный объект, при use strict, this будет null.

this может указывать на что угодно, это зависит только от того, как вы его называете.

  • test(): использует глобальный объект (exports) как this, если только в строгом режиме, где this будет null;
  • test.call({}) или test.apply({}): Вы указываете, что использовать как this (первый параметр)
  • var obj = {testRef: test}; obj.testRef(): this устанавливается слева от ., то есть obj

Противодействие ответ на этот вопрос

Верно, что this на верхнем уровне модуля exports, но это не обязательно означает, что this внутри test() также укажет на то же, что и там, откуда он был вызван.


Попытка доказать, что this и глобальный объект указывают на exports

 myGLobal = 5;
 this.myGlobal; // 5