全局范围和对象范围内的上下文和词法环境

Context and Lexical environment in the global scope and object scope

我是 javascript 的新手,我对上下文和词法环境感到困惑。

案例一:

我在全局范围内:

function fun() {
    console.log("It works!");
}
fun(); //prints It works!
this.fun(); //also prints It works!

当我写 fun(); 时,我假设 this 上下文是隐含的吗?没有 this 关键字?基本上,这里 this === global/window。我的问题是,当我键入 fun() 时,是否隐含了 this 就像我键入 this.fun(); 一样?还是当我键入 fun(); 时的情况?如果没有 this 关键字,JavaScript 会在全局范围级别查看词法环境,即它会查看是否在其当前范围内声明了一个有趣的全局函数?

案例二:

let cat = {
  purr: function() {
    console.log("meow");
  },
  purrMore: function() {
    for (let i = 0; i < 10; i++) {
      purr();
    }
  }
};

cat.purr();
cat.purrMore();

为什么当我在没有 this. 的情况下在 purrMore 中调用 purr 时,会出现引用错误?如果案例 1 中的 fun 函数在没有 this 的情况下工作,那么它不应该在没有 this 的情况下工作吗?

我的困惑如下:如果在情况 1 中,有趣的函数调用没有 this。关键字有效是因为 this。是隐含的,然后在没有 this 的情况下调用 purr 函数。也应该工作。但是如果fun函数调用没有this。关键字使用词法环境,那么情况 2 不起作用更有意义。但是,为什么这段代码有效:

function purr() {
    console.log("MEOW")
}

let cat = {
  purr: function() {
    console.log("meow");
  },
  purrMore: function() {
    for (let i = 0; i < 10; i++) {
      purr();
    }
  }
};

cat.purr();
cat.purrMore(); //prints MEOW ten times

为什么 cat 对象中的 purr 函数不出现在 purrMore 的词法环境中?

最后,我应该参考哪些主题或资源以消除我的知识空白?

在第二种情况下,您使用方法 purr 定义对象 cat,但在调用 purr() 时未引用该对象。 Javascript 正在查看全局范围以查找函数 purr(),未找到它,并抛出引用错误。

工作示例:

let cat = { 
  purr: function() { //<-- defined a
    console.log("meow");
  },
  purrMore: function() {
    for (let i = 0; i < 10; i++) {
     this.purr(); // <-- "this" is the `cat object`
    }
  }
};

cat.purr();
cat.purrMore(); 

在您的第二个示例中,在情况二中,您在全局范围内 定义 purr()...

function purr() {
    console.log("MEOW")
}

...使引用有效。

我找到的了解 javascript 对象和作用域的最佳资源在这里:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

“词法作用域”的另一个例子是 here

I am confused over context and lexical environments.

请记住,它们是完全独立的实体:

  • 默认情况下,this 上下文是 undefined,它仅在 a) 方法调用 b) 草率模式中假定一个值。
  • 词法环境不是javascript对象,它只存储声明的变量。它不受 this 值的影响。
"use strict";
const fun = function() {
    console.log(this);
}
fun(); // prints `undefined`
window.fun(); // throws exception

Am I correct to assume that the this context is implied when I write fun(); without the this keyword?

没有。 fun 在词法作用域中查找,在其他任何地方查找。

Or is it the case that when I type fun(); without the this keyword, JavaScript looks into the lexical environment at the global scope level i.e. it looks if there is a fun function declared in it's current scope that is global?

是的。在您的第一个示例中,没有局部作用域,因此它正在寻找 fun 全局作用域,它会在其中找到声明的函数。在您的 purr() 示例中,它首先在循环的块范围内查找,然后在函数范围内查找,然后在全局范围内查找 function purr.

全局范围是一个例外,因为与其他范围不同,它(的一部分)由一个对象作为存储支持,即全局对象。不过,您通常不会使用它。