此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();
这是Babel中的错误还是规范本身不允许这样做?
答案 0 :(得分:4)
似乎这是ES6的预期行为。 在Chrome控制台上测试,也出现了错误。
ES6规范说到了这一点:
- 让parameterNames成为形式的BoundNames。 http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation
醇>
这意味着当你创建函数时,ES6将像babel一样基本相同,它将在新的上下文中管理params的赋值。
在javascript中,当您在封闭范围内创建变量a
时,无法再访问全局a
,因为JS将从最近的可能范围中取a
, AST。
简单示例:
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的值,然后将其分配给内部a,是因为提升,基本上是这样做的:
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 }
}