简体   繁体   English

Javascript let 关键字如何防止重新定义?

[英]How Javascript let keyword prevents re-defining?

I'm python developer.我是python开发人员。 In python, When you want to check whether a variable is already defined, you use dict在python中,当你想检查一个变量是否已经定义时,你使用dict

memo = {}
if 'a' not in memo:
    memo['a'] = 'var_a'

javascript let keyword has similar functionality, it prevents re-defining. javascript let 关键字具有类似的功能,它可以防止重新定义。

let a = 1;
let a = 2; // SyntaxError

So how let achieves this functionality under the hood?那么let如何在底层实现这个功能呢? Does V8 engine keeps some kind of HashMap of let variables? V8 引擎是否保留某种让变量的 HashMap?

Does V8 engine keeps some kind of HashMap of let variables? V8 引擎是否保留某种让变量的 HashMap?

Essentially, yes - though it's not a V8 thing in particular, it's something that all spec-compliant JavaScript engines must adhere to.从本质上讲,是的——尽管它不是 V8 的东西,但它是所有符合规范的 JavaScript 引擎都必须遵守的东西。 It's called an environment record , which in this case is a "lexical environment", which is, to oversimplify, a collection of identifiers for a given scope and the values that the identifiers hold at that point.它被称为环境记录,在这种情况下,它是一个“词法环境”,为了简化,它是给定范围的标识符的集合以及标识符在该点所持有的值。

When a function is evaluated, FunctionDeclarationInstantiation runs, which does, among many other things:当一个函数被评估时, FunctionDeclarationInstantiation会运行,它会执行许多其他操作:

34. For each element d of lexDeclarations, do
  a. (unimportant; omitted)
  b. For each element dn of the BoundNames of d, do
    i. If IsConstantDeclaration of d is true, then
      1. Perform ! lexEnv.CreateImmutableBinding(dn, true).
    ii. Else,
      1. Perform ! lexEnv.CreateMutableBinding(dn, false).

The lexDeclarations include identifiers declared with let or const inside the function. lexDeclarations包括在函数内用letconst声明的标识符。 This list cannot have duplicate entries as a result of an Early Errors requirement, which says, for blocks:由于Early Errors要求,此列表不能有重复条目,该要求表示,对于块:

It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries.如果 StatementList 的 LexicallyDeclaredNames 包含任何重复条目,则为语法错误。

Identifiers declared with var s are slightly different - they're not LexicallyDeclaredNames, but VarDeclaredNames instead, which have no requirement against being listed multiple times in a block.var声明的标识符略有不同——它们不是 LexicallyDeclaredNames,而是 VarDeclaredNames,它不需要在一个块中多次列出。 This doesn't result in duplicate var names being created multiple times in the environment because the duplicate declarations are explicitly skipped from the CreateMutableBinding call:这不会导致在环境中多次创建重复的var名称,因为重复声明已从CreateMutableBinding调用中 显式跳过

e. For each element n of varNames, do
  i. If n is not an element of instantiatedVarNames, then
    1. Append n to instantiatedVarNames.
    2. Perform ! varEnv.CreateMutableBinding(n, false).
    ...

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

相关问题 ES6:重新定义导出的函数 - ES6: Re-defining exported function 变量在函数中定义,但需要重新定义 - Variable is defined in the function but needs re-defining 用冲突的局部变量重新定义全局变量 - Re-defining global variable with conflicting local variable 在为QScriptEngine重新定义“print()”函数时返回“未定义值”有什么意义? - What's the point of returning an “Undefined Value” when re-defining “print()” function for QScriptEngine? let和const与javascript'this'关键字的行为 - behavior of let and const with javascript 'this' keyword 在Javascript中定义变量时使用var关键字 - Using var keyword when defining a variable in Javascript 在Safari Javascript中无法使用“let”关键字? - Can't use “let” keyword in Safari Javascript? 我们必须在 javaScript For 循环中包含 Let 关键字吗? - Must we include Let keyword in javaScript For Loops? 在JavaScript中,如果“功能”源自“对象”,那么在定义对象的构造函数时如何使用关键字功能? - In JavaScript if “Function” descends from “Object”, then how was keyword function made available while defining the constructor of object? 如果我们可以从循环外部访问它,那么如何让关键字块在 JavaScript 范围内 - How is let keyword block scoped in JavaScript if we can access it from outside the loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM