JavaScript类奇怪的范围

时间:2018-04-27 07:21:25

标签: javascript node.js scoping

假设我有两个文件。一个文件,其中方法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 } 

一切都按预期工作,this方法中的hello()具有正确的范围。 但是,当我创建一个新的类实例并导出只是 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>

2 个答案:

答案 0 :(得分:2)

当你单独调用hello()时,它没有调用上下文 - 当所述对象通常是它的调用上下文时,它不是从对象调用的。 (例如Test.hello(); - 调用上下文在该行中为Test

如果要绑定其调用上下文以使其可用作独立函数,则应导出绑定函数,例如:

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

答案 1 :(得分:1)

他们有不同的背景:
在第一种情况下,&#34;你好&#34;绑定到&#34;测试&#34;对象。
在第二个,&#34;你好&#34;绑定到全球范围&#34;这是&#34;未定义&#34;。
如果你在网络浏览器中运行第二个,你会得到&#34; window&#34;对象,它是浏览器中的全局上下文。