ES6 javascript阻止范围变量提升到标题

时间:2017-02-18 06:18:40

标签: javascript ecmascript-6 hoisting

for循环块中的所有块范围变量是否都高于循环标题本身?

{{1}}

每次将i与循环标题中的x进行比较时,是否会在x上产生死区错误?我理解我在块范围内被推下,但为什么不在x?

4 个答案:

答案 0 :(得分:1)

语言规范的相关部分为13.7.4

如果for语句包含letconst声明,则会创建范围。

如果for语句包含let声明,则每次迭代都会创建一个范围。

如果for body是一个块,则会创建一个范围。

以下是一些示例和创建的范围:

//no scope
for(i = 0; i<3; i++) console.log(i);

//no scope
for(var i = 0; i<3; i++) console.log(i);

//for scope and iteration scope
for(let i = 0; i<3; i++) console.log(i);


// for scope, iteration scope and block scope
for(let i = 0; i<3; i++) {
  console.log(i);
}

为什么我们需要迭代范围?关闭:

for(let i = 0; i<3; i++) {
  setTimeout(() => console.log(i), 10);
}

没有迭代范围的输出:3,3,3。使用迭代范围:0,1,2

答案 1 :(得分:0)

  

for循环块中的所有块范围变量是否都高于循环标题本身?

不,它们在块范围内悬挂

  

每次将i与循环标题中的x进行比较时,是否会在x上产生死区错误?我理解我在块范围内被推下,但为什么不在x?

不,因为循环标头中的$plainXML = mungXML($soapXML); $arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML, 'SimpleXMLElement', LIBXML_NOCDATA)), true); // FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE function mungXML($xml) { $obj = SimpleXML_Load_String($xml); if ($obj === FALSE) return $xml; // GET NAMESPACES, IF ANY $nss = $obj->getNamespaces(TRUE); if (empty($nss)) return $xml; // CHANGE ns: INTO ns_ $nsm = array_keys($nss); foreach ($nsm as $key) { // A REGULAR EXPRESSION TO MUNG THE XML $rgx = '#' // REGEX DELIMITER . '(' // GROUP PATTERN 1 . '\<' // LOCATE A LEFT WICKET . '/?' // MAYBE FOLLOWED BY A SLASH . preg_quote($key) // THE NAMESPACE . ')' // END GROUP PATTERN . '(' // GROUP PATTERN 2 . ':{1}' // A COLON (EXACTLY ONE) . ')' // END GROUP PATTERN . '#' // REGEX DELIMITER ; // INSERT THE UNDERSCORE INTO THE TAG NAME $rep = '$1' // BACKREFERENCE TO GROUP 1 . '_' // LITERAL UNDERSCORE IN PLACE OF GROUP 2 ; // PERFORM THE REPLACEMENT $xml = preg_replace($rgx, $rep, $xml); } return $xml; } print_r($arrayResult); 引用x定义为4 x

在声明范围和声明之间的时间是TDZ之前,您无法访问var x = 4变量。

离。

let

答案 2 :(得分:0)

test run

基于此,我认为x只适用于范围。

答案 3 :(得分:0)

我误解了,并且认为只有一个块范围。我不愿意在表达式i < x中取两个任意变量,并且必须决定查找哪个块范围,这是不可能确定的。

正确的方法是构建两个嵌套的块作用域,一个用于循环头,另一个用于循环体。这意味着在循环头和循环体范围中都可以看到let i,并且循环中的let x仅在循环体范围中看到。容易腻,柠檬挤压。