Javascript如何声明函数参数?

时间:2017-10-11 14:45:21

标签: javascript ecmascript-6

function func(x = y, y = 2) { 
    return [x, y];
}

func(); // ReferenceError: y is not defined
func(1); // [1, 2]

如上面的代码暗示,函数参数范围中有一个隐藏的TDZ,这解释了为什么下面的代码失败:

function func(arg) {
    let arg = 1; // SyntaxError: Identifier 'arg' has already been declared
}

所以函数参数应该用let声明,但让我困惑的是:

function func(arg) {
    var arg = 1;
    console.log(arg); // 1
}

此代码工作正常。

为什么你可以使用var重新声明变量? Javascript如何声明函数参数?

编辑: 我确切地知道你不能使用let来重新声明变量。这里的问题是函数参数是否使用let声明,所以:

function func(arg) {
    var arg = 1;
}

就像:

let arg; // arg parameter declares here
var arg = 1; // func body 

为什么这可以毫无例外地运行?

7 个答案:

答案 0 :(得分:3)

  

函数参数范围中有一个隐藏的TDZ

确实是的。看看here以获取更多示例。

  

Javascript如何声明函数参数?

作为参数 - 请参阅here以获取逐步说明。它们既不是let也不是var,它们有自己的语义。引入默认初始化程序的ES6给予它们与let中相同的TDZ限制,以捕获更多程序员错误。

  

为什么您可以使用var重新声明变量?

因为在ES5之前,重新声明变量不是错误条件,并且需要保留此行为以不破坏Web。它只能用于新功能,例如letconst - 或使用默认初始值设定项的参数列表,请尝试function x(bar, bar) {} vs function x(bar, bar=1){}

答案 1 :(得分:1)

这并不一定与函数的论据有关。

这也会引发错误:



function func() {
    var arg = 1;
    let arg = 2
    console.log(arg); // 1
}

func();




您无法使用let 重新声明变量,而var并非严格:var不会如果变量已经声明,则尝试重新声明变量。它只是分配新值。

有关let详细信息的详细信息,请参阅this MDN page on the let statement.

答案 2 :(得分:1)

原因在于,JavaScript社区中的人称之为"吊装"当你var arg = 1转换为var arg; arg = 1;时,如果由于函数参数已经定义了var,那么编译器会尝试帮助并忽略后续重新声明而不是抛出错误......这可能是一个意外的行为,并且没有使用新的let变量声明,但是,由于向后兼容的原因,它必须保持在那里。

答案 3 :(得分:0)

最近添加了

let并且随之添加了错误抛出,当您尝试声明涉及let两次的变量时,会出现错误抛出。 var只会替换旧值,除非已使用let声明变量,否则不会发生这种情况。

function func(arg) {
    let arg = 1; // not ok, because `let` knows that `arg` is being redeclared
}

function func(arg) {
    var arg = 1; // ok, because `var` will just replace the value of `arg`
}

function func() {
    let arg = 0;
    var arg = 1; // not ok, because `let` declared `arg` already
}

以下是MDN for let的链接,其中说明了该功能。

答案 4 :(得分:0)

所以var是遗留语法,理想情况下你可能想避免使用它。

而是将let用于可以重新分配的变量,而将const用于常量。

var也具有全球范围,其中letconst仅限于其所在的范围。

答案 5 :(得分:0)

参数绑定并不完全遵循与let声明的行为相同的行为。

1)参数绑定在var绑定之前创建。 var不会创建已存在的绑定,因此从来没有问题。但let会在var之后创建绑定。

2)在创建范围的所有产品上都存在早期错误,通常情况下,当已经存在具有相同名称的变量声明时,不会发生词法绑定。

答案 6 :(得分:-2)

如果将参数传递给func调用,第一个示例不会将错误值抛出。

varletconst的范围不同。