TDZ在函数参数的未声明变量中 [英] TDZ in undeclared variables of function parameters

查看:46
本文介绍了TDZ在函数参数的未声明变量中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试运行此代码段中定义的foo函数时,由于未定义 b ,因此会收到 ReferenceError .

When I try to run the foo function defined in this snippet I get a ReferenceError since b is not defined.

var b = 3;

function foo( a = 42, b = a + b + 5 ) {
    // ..
}
foo()

这看起来像是TDZ错误,因为b已在外部范围中定义,但尚未在函数签名中用作右侧值.

This looks like a TDZ error because b has been defined in the outer scope but it's not yet usable in the function signature as a right-hand-side value.

这是我认为编译器应该做的:

This is what I think the compiler should do:

var b;
function foo(..) { .. }

// hoist all functions and variables declarations to the top

// then perform assignments operations

b = 3;
foo();

//create a new execution environment for `foo`
// add `foo` on top of the callstack

// look for variable a, can't find one, hence automatically create a 
   `var a` in the local execution environment and assign to it the 
    value `42`
// look for a `var b` in the global execution context, find one, use 
   the value in it (`3`) as a right-hand-side value.

这不应引发ReferenceError.看起来这不是这里发生的事情.

This shouldn't raise a ReferenceError. Looks like this is not what happens here.

有人可以解释编译器的实际作用以及如何处理此代码吗?

Can someone explain in what actually does the compiler do and how it processes this code?

推荐答案

在每个函数调用中,引擎都会评估一些序言代码,其中包含形式参数,声明为 let vars,并使用其实际值进行初始化值或默认表达式(如果提供):

On every function call, the engine evaluates some prologue code, which contains formal parameters, declared as let vars and initialized with their actual values or default expressions, if provided:

var b = 3;

function foo( ) {
    let a = <actual param for a> OR 42;
    let b = <actual param for b> OR a + b + 5;
   // ..
}

由于函数中的 b 是词法( let ),因此无法在初始化之前访问其值.因此是ReferenceError.

Since b in a function is lexical (let), it's not possible to access its value before initialization. Hence the ReferenceError.

请注意,这是一个调用时错误,因此可以进行以下编译:

Note that this is a call-time error, so the following compiles fine:

var b = 1

function foo(b=b) {
  console.log(b)
}

当您实际调用函数时发生错误:

The error happens when you actually call the function:

var b = 1

function foo(b=b) {
  console.log(b)
}

foo() 

并且仅在引擎实际评估错误的默认表达式时:

and only when the engine actually evaluates the faulty default expression:

var b = 1

function foo(b=b) {
  console.log(b)
}

foo(7) 

ECMA标准参考: FunctionDeclarationInstantiation ,第21页:

ECMA standard reference: FunctionDeclarationInstantiation, p.21:

对于parameterNames中的每个String paramName,请执行

For each String paramName in parameterNames, do

...执行!envRec.CreateMutableBinding(paramName,false).

...Perform ! envRec.CreateMutableBinding(paramName, false).

这篇关于TDZ在函数参数的未声明变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆