在 Javascript 中,什么时候创建新的作用域? (使用新函数并在“with”语句中)这是唯一的两种情况吗?

发布于 2024-08-30 19:26:16 字数 244 浏览 3 评论 0原文

在 Javascript 中,什么时候创建新的作用域?我知道的两种情况是:

  1. 一个新函数(更新于2012/09,我认为它需要是函数调用,而不仅仅是函数定义)
  2. 在“with”语句中

使用 请注意,任何新块(在 if-then-else、循环中或只是出于其他原因开始块)都不会创建新作用域。

除了上述两种情况之外,是否还有第三种创建新作用域的情况?谢谢。

In Javascript, when is a new scope created? The 2 situations I know of are:

  1. with a new function (update on 2012/09, I think it needs to be a function invocation, not just a function definition)
  2. in a "with" statement

as a note, any new block (in if-then-else, loops, or just beginning a block for no other reason) won't create a new scope.

Is there a third situation where a new scope is created besides the two situations above? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

假装爱人 2024-09-06 19:26:16

是的,还有第三种情况,即作用域链被增强(除了 Shog9 提到),当 catch块被评估:

生产捕获:捕获
(标识符)块被评估为
如下:

  1. 令 C 为已传递给此产生式的参数。

  2. 创建一个新对象,就像使用表达式 new Object() 一样。

  3. 在对象 Result(2) 中创建一个属性。该房产的名称是
    标识符,值为C。值,以及
    属性为 { DontDelete }。

  4. 将 Result(2) 添加到作用域链的前面

  5. 评估块。

  6. 作用域链前面删除 Result(2)。

  7. 返回结果(5)。

因此,基本上,创建了一个新对象,其名称类似于传递给catch的标识符的属性,这个新对象被添加到作用域链中,因此我们可以在中使用该标识符catch 块。

try {
  throw "error";
} catch (identifier) {
  // `identifier` accessible here..
}

但请记住,它只是暂时增强当前范围,引入catch标识符,其中声明的任何变量都将提升到它的顶部包含函数。

Yes, there is a third case where the scope chain is augmented (besides the let mozilla-extension that Shog9 mentions), when a catch block is evaluated:

The production Catch : catch
(Identifier ) Block is evaluated as
follows:

  1. Let C be the parameter that has been passed to this production.

  2. Create a new object as if by the expression new Object().

  3. Create a property in the object Result(2). The property's name is
    Identifier, valueisC. value, and
    attributes are { DontDelete }.

  4. Add Result(2) to the front of the scope chain.

  5. Evaluate Block.

  6. Remove Result(2) from the front of the scope chain.

  7. Return Result(5).

So basically, a new object is created, with a property named like the Identifier passed to catch, this new object is added to the scope chain, so we are able to use that identifier within the catch block.

try {
  throw "error";
} catch (identifier) {
  // `identifier` accessible here..
}

But keep in mind that it only augments the current scope temporarily, to introduce the catch Identifier, any variable declared inside will be simply hoisted to the top of it enclosing function.

撩动你心 2024-09-06 19:26:16

还有 let 语句。请记住,let (...) {}with (...){} 一样,不会为其中引入的变量创建新作用域 块。然而,定义可以< /em> 创建作用域为定义它们的块(任何块)的变量。

公平警告: 正如注释中所指出的,而 let 是 JavaScript 的一部分1.7(ECMA-262/ECMAScript 的 Mozilla 方言),它不是 ECMAScript 的一部分,并且可能很快无法在 Firefox 以外的浏览器中运行。另请注意,虽然 with可以用作 ECMAScript 当前实现中 let 语句的替代品,为待定的 ECMA-262 第五版提出的“严格”模式也不允许这样做。如果您担心编写跨平台、面向未来的代码(并且您应该...),那么坚持使用范围控制函数

There's also the let statement. Keep in mind that let (...) {}, like with (...){}, does not create a new scope for variables introduced within the block. However, let definitions can create variables scoped to the block (any block) they're defined in.

Fair warning: as has been pointed out in comments, while let is part of JavaScript 1.7 (the Mozilla dialect of ECMA-262/ECMAScript), it is not part of ECMAScript, and will likely not work any time soon in browsers other than Firefox. Also note that while with can be used as a stand-in for let statements in current implementations of ECMAScript, the "strict" mode proposed for the pending ECMA-262 5th edition disallows this as well. If you're concerned about writing cross-plaform, future-proof code (and you should be...) then stick with functions for scope control!

庆幸我还是我 2024-09-06 19:26:16

这也将引用您所在的对象:

a = {
   f: function(){ ... },
   b: function(){this.f()}
}
a.b() //calls a.f

this will also refer to the object you are in:

a = {
   f: function(){ ... },
   b: function(){this.f()}
}
a.b() //calls a.f
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文