2017-01-23 13 views
2

スコープ:私は<a href="http://exploringjs.com/es6/ch_variables.html#ch_variables" rel="nofollow noreferrer">this book on ES6</a>を読んでいると、次がある

Function declarations…

  • are block-scoped, like let.
  • create properties in the global object (while in global scope), like var.
  • are hoisted: independently of where a function declaration is mentioned in its scope, it is always created at the beginning of the scope.

私の知る限り、関数は、常に関数がスコープされています。私は何かがES6に変更されているかもしれないと思ったが、いや:

function a() { 
    if (true) { 
     // defined inside the block and is hoisted to the top of that block 
     z(); 
     function z() { console.log ('z')} 
    } 

    z(); 
} 

// but is also hoisted to the function scope 
a(); // works OK 

は実際に、彼らはブロックのように見えるスコープ:

function a() { 
    if (false) { 
     // defined inside the block and is hoisted to the top of that block 
     z(); 
     function z() { console.log ('z')} 
    } 

    z(); // error 
} 

は、だから、ES6に変わりましたか?

+0

本書では、「let」がどのように絵に収まるかを説明するための例として(既存の)関数宣言を使用していると思います。 – Lucero

+1

これは、あなたが緩いモードで実行しているからです。厳密モードでは、期待どおりになるはずです。 – estus

答えて

5

AFAIK, functions have always been function scoped. I thought something might have changed in ES6

これは、ES2015より前のバージョンでは、ブロック内で宣言された関数をまったく対象としていませんでした。それらをサポートすることは許可されていましたが、仕様の一部ではありませんでした。

したがって、仕様は、特にブラウザのルースモードでは、フープを飛び越えなければなりません。 厳格モードで

、あなたは宣言を機能対応のエンジンで見つけることができます実際にブロックスコープです:(などでV8のように準拠したJavaScriptエンジンで

"use strict"; 
 

 
function test() { 
 
    if (true) { 
 
    function foo() { 
 
     console.log("foo called"); 
 
    } 
 
    } 
 
    try { 
 
    foo(); // ReferenceError 
 
    } catch (e) { 
 
    console.log("Error: " + String(e)); 
 
    } 
 
} 
 
test();

Chromeの最近のバージョン、またはFirefoxの最近のバージョンのSpiderMonkey)を使用すると、上にReferenceErrorが表示されます。

+0

@TJCrowder @TJCrowder Firefoxの場合SyntaxError:strictモードのコードでは、関数はトップレベルで宣言されているか、別の関数内ですぐに宣言される可能性があります。 – Eineki

+0

@Eineki:かなり古いバージョンのFirefoxでなければなりませんES2015-サポート - 土地:-))。 Firefox v50.1.0で期待される 'ReferenceError'を取得しました。 –

関連する問題