2016-07-11 16 views
7

の既定のパラメータと同じ引数名を使用して:にTranspiledこのES6コードES6

const log =() => console.log('hi'); 
const parent = (log = log) => log(); 
parent(); 

var log = function log() { 
    return console.log('hi'); 
}; 
var parent = function parent() { 
    var log = arguments.length <= 0 || arguments[0] === undefined ? log : arguments[0]; 
    return log(); 
}; 
parent(); 

はエラーを与える:

return log(); 
     ^
TypeError: log is not a function 

問題は、この行です:

const parent = (log = log) => log(); 

引数名がデフォルトパラメータと同じであるためです。

これは動作します:

const log =() => console.log('hi'); 
const parent = (logNow = log) => logNow(); 
parent(); 

これはバベルのバグですか、この仕様自体に許可されていませんか?

+1

巻上げは、この問題が発生します。 –

答えて

3

これはES6の予想される動作です。 Chromeコンソールでテストしたところ、エラーが発生しました。

ES6仕様は、その時点までに言っている:あなたは関数を作成するとき

  1. Let parameterNames be the BoundNames of formals. http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation

これは、ES6は基本的に同じようなバベルがやっているんだろう意味、それは新しいコンテキストでのparamsの割り当てを管理します。 JSはASTに、できるだけ近い範囲からaがかかりますので、JavaScriptで

、あなたが閉じられた範囲内の変数aを作成し、グローバルaは、もはやアクセスすることはできません。

簡単な例:

var a = 1; 
function test() { 
    // creates the variable a, and try to assign a value to it, 
    // because `a` is now available in the scope itself, it will take value of a in the inner scope, not the outer scope one 
    var a = a; 
    console.log(a) 
} 
test() // undefined 

なぜ、外の値をとり、その後、インナーAに割り当てないITSは理由巻上げであり、基本的には、このこと:

function test() { 
    var a; // the address for the variable is reserved at compile time 
    a = a; // run-time assignment 
} 

関数のすべての変数宣言を受け取り、それを関数の先頭に移動します。

これは、このような何かが動作する理由、次のとおりです。

function hoistingTest(n, m = 2) { 
    // return immediately 
    return multi(n); 

    // This declaration will be hoisted to the begin of the body 
    function multi(n) { return m * n } 
} 
+0

元のコードをChromeのコンソールにコピーするだけで、速い証明が必要な場合は、この回答が示すように動作します –