Предполагая, что у меня есть два файла. Один файл с классом, где метод hello просто console.infos this:
// Class.js
class Test {
constructor() {
this.inside = true;
}
hello() {
console.info('inside hello')
console.info(this);
}
}
module.exports = new Test();
и еще один файл, который выполняет метод hello этого класса:
// index.js
const Test = require('./Class.js');
Test.hello();
// -> 'inside hello'
// -> { inside: true }
Все работает как положено, this в методе hello() имеет правильный прицел.
Но, когда я создаю новый экземпляр класса и экспортирую простоhello этого нового экземпляра:
// Class.js
class Test {
constructor() {
this.inside = true;
}
hello() {
console.info('inside hello')
console.info(this);
}
}
module.exports = (new Test()).hello; // <- just hello is exported
затем область видимости hello() изменилась, и кажется, что он больше не является частью класса:
// index.js
const hello = require('./index.js');
hello();
// -> 'inside hello'
// -> undefined
Есть ли причина, по которой эта единственная экспортируемая функция действует так по-разному?
Я пробовал это на Python, и это сработало (может быть, и на других языках):
# Class.py
class Class:
def __init__(self):
self.test = 'hello'
def hello(self):
print('inside hello')
print(self)
hello = Class().hello
# index.py
from Class import hello
hello()
# -> 'inside hello'
# -> <Class.Class instance at 0x10e26e488>
Я считаю, что вы можете экспортировать не только метод, а только экземпляр объекта с этим методом.
В отличие от большинства языков, this в Javascript не передается с методами, .. В простейшей форме, если вы не используете . (точка) для вызова своей функции, Javascript не может узнать этот контекст, .. Это было привязка / вызов и т. д. вступают в игру.
Возможный дубликат Как работает ключевое слово "это"?
здесь есть специфика NodeJ, в браузере контекстом был бы глобальный this, то есть window. Узел ведет себя по-разному с точки зрения глобального материала. Кроме того, this в JS исходит из контекста выполнения, а не из создания, это зависит от того, где он вызван, если не привязан



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


Когда вы вызываете hello() в автономном режиме, у него нет контекста вызова - он не вызывается из объекта, когда указанный объект обычно будет контекстом его вызова. (например, Test.hello(); - контекст вызова будет Test в этой строке)
Если вы хотите привязать его контекст вызова, чтобы его можно было использовать как отдельную функцию, вам следует экспортировать функцию граница, например:
const test = new Test();
module.exports = test.hello.bind(test);
У них разный контекст:
В первом случае "hello" привязывается к объекту "Test".
Во втором «hello» привязывается к «global scope», которая равна «undefined» .
Если вы запустите второй в веб-браузере, вы получите объект «окно», который является глобальным контекстом в браузере.
thisвсегда является объектом, для которого вызывается функция. Вы вызываетеhelloнапрямую, поэтомуthisне определен.