首页 > 解决方案 > JavaScript 类奇怪的作用域

问题描述

假设我有两个文件。一个带有类的文件,其中方法hello只是 console.logs this

// Class.js
class Test {
  constructor() {
    this.inside = true;
  }

  hello() {
    console.log('inside hello')
    console.log(this);
  }
}

module.exports = new Test();

和另一个执行hello此类方法的文件:

// index.js
const Test = require('./Class.js');

Test.hello();
// -> 'inside hello'
// -> { inside: true } 

一切都按预期工作,thishello()方法具有正确的范围。 但是,当我创建一个类的新实例并 hello导出这个新实例时:

// Class.js
class Test {
  constructor() {
    this.inside = true;
  }

  hello() {
    console.log('inside hello')
    console.log(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>

标签: javascriptnode.jsscoping

解决方案


当您调用hello()独立时,它没有调用上下文 - 它不是从对象调用的,而该对象通常是它的调用上下文。(例如Test.hello();- 调用上下文将Test在该行中)

如果你想绑定它的调用上下文以便它可以作为一个独立的函数使用,你应该导出绑定的函数,例如:

const test = new Test();
module.exports = test.hello.bind(test);

推荐阅读