简体   繁体   English

将 Let 变量声明与 With 语句一起使用

[英]Use Let variable declaration with With Statement

I read about with statement from Ecma Specification and in there with statement evaluation like this.我从 Ecma Specification 中阅读了 with 声明,并在其中阅读了这样的声明评估。

  1. Let val be the result of evaluating Expression.设 val 为 Expression 求值的结果。
  2. Let obj be?让 obj 成为? ToObject(? GetValue(val)). ToObject(?GetValue(val))。
  3. Let oldEnv be the running execution context's LexicalEnvironment.设 oldEnv 为正在运行的执行上下文的 LexicalEnvironment。
  4. Let newEnv be NewObjectEnvironment(obj, oldEnv).设 newEnv 为 NewObjectEnvironment(obj, oldEnv)。
  5. Set the withEnvironment flag of newEnv's EnvironmentRecord to true.将 newEnv 的 EnvironmentRecord 的 withEnvironment 标志设置为 true。
  6. Set the running execution context's LexicalEnvironment to newEnv.将运行执行上下文的 LexicalEnvironment 设置为 newEnv。
  7. Let C be the result of evaluating Statement.令 C 为 Statement 的评估结果。
  8. Set the running execution context's LexicalEnvironment to oldEnv.将运行执行上下文的 LexicalEnvironment 设置为 oldEnv。
  9. Return Completion(UpdateEmpty(C, undefined)).返回完成(UpdateEmpty(C,未定义))。

If with statement use Lexical Environment for evaluation why my sample code not work?如果 with 语句使用词法环境进行评估,为什么我的示例代码不起作用?

const user = {
   fullName: "Murad Sofiyev"
};
with(user) {
    let firstName = "Tofiq";
    fullName = "Tofiq Sofiyev";
}

console.log(user.firstName); // Undefined
console.log(user.fullName); // Tofiq Sofiyev

PS: I know with statement is deprecetaed but this is help me to understand Lexical Environment and Variable Environment:) PS:我知道 with 声明已被弃用,但这有助于我理解词法环境和变量环境:)

The { following the with(user) creates an entirely new LexicalEnvironment. with(user)之后的{创建一个全新的LexicalEnvironment。 There are actually two environments created there: the environment for the with 'd object, and the environment for the new { block.实际上在那里创建了两个环境: with 'd object 的环境和新{块的环境。 When you use let firstName = "Tofiq";当你使用let firstName = "Tofiq"; , you're creating a new variable name inside the inner (block-scoped) environment. ,您正在内部(块范围)环境中创建一个新变量名。

This might be a bit more obvious if you can see that you can use with without a paired { :如果您可以看到可以在没有配对{的情况下使用with ,这可能会更明显一点:

 const user = { firstName: 'foo', }; with(user); console.log('Not a syntax error');

Here, the environment created by the with 'd value is created, and goes completely unused.在这里,由with 'd 值创建的环境被创建,并且完全未被使用。 (and there's no inner environment). (并且没有内部环境)。

Another issue is that firstName doesn't exist on the object.另一个问题是 object 上不存在firstName If the object had the firstName property and you used var instead of let , the new Tofiq would be assigned to the object.如果 object 具有firstName属性并且您使用var而不是let ,则新的Tofiq将分配给 object。

 const user = { firstName: 'foo', }; with(user) { var firstName = "Tofiq"; } console.log(user.firstName); // Tofiq // because var is not block-scoped // so `var firstName` finds an outer Lexical Environment with that same variable name

Using let always creates a variable in block scope.使用let总是在块 scope 中创建一个变量。 So even though you use it inside the with block, it is creating a new variable scope to the with .因此,即使您在with块中使用它,它也会为with创建一个新变量 scope 。 You might want that behaviour if you needed to do some calculations inside the block.如果您需要在块内进行一些计算,您可能需要这种行为。

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

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