简体   繁体   English

JavaScript类奇怪的作用域

[英]JavaScript Class Weird Scoping

Assuming I have two files. 假设我有两个文件。 One file with a class where the method hello just console.logs this : 一个文件,一个类,其中方法hello刚刚console.logs this

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

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

module.exports = new Test();

and another file which executes the method hello of this class: 和另一个执行此类的方法hello的文件:

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

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

Everything works as expected, the this in the hello() method has the correct scope. 一切都按预期工作, hello()方法中的this具有正确的作用域。 But , when I make a new instance of the class and export just hello of this new instance: 但是 ,当我把课和出口只是一个新实例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

then the scoping of the hello() changed and it seems it is not a part of the class anymore: 然后hello()的作用域发生了变化,似乎它不再属于该类的一部分:

// index.js
const hello = require('./index.js');

hello();
// -> 'inside hello'
// -> undefined

Is there a reason, why this single exported function acts so differently? 为什么有一个原因,为什么单个导出函数的行为如此不同?


I tried it in Python, and it worked (maybe it does in other languages as well): 我在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>

When you call hello() standalone, it has no calling context - it's not being called from an object, when said object would ordinarily be its calling context. 当您单独调用hello() ,它没有调用上下文-当该对象通常是其调用上下文时,不会从对象中调用它。 (such as Test.hello(); - the calling context would be Test in that line) (例如Test.hello(); -调用上下文为该行中的Test

If you want to bind its calling context so that it's usable as a standalone function, you should export the bound function, such as: 如果要绑定其调用上下文以使其可用作独立函数,则应导出绑定的函数,例如:

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

They have different context: 它们具有不同的上下文:
In first case, "hello" binds to "Test" object. 在第一种情况下,“ hello”绑定到“ Test”对象。
In second one, "hello" binds to "global scope" which is "undefined". 在第二篇中,“ hello”绑定到“未定义”的“全局范围”。
If you run second one in web browser, you will get "window" object which is the global context in browser. 如果在Web浏览器中运行第二个,则将获得“窗口”对象,该对象是浏览器中的全局上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM