声明只是说某事存在。在 JavaScript 中,您可以声明变量、函数和(最近的)类。
在某些语言(例如 C、C++)中,可以声明某些东西而无需定义它。例如:
// this declares a function exists with a given signature, but doesn't define its implementation
void someFunction();
someFunction(); // here we call the function, since we know it exists
// here we define the function, which we have to do at some point
void someFunction() { /* ... */ }
这种模式在现代语言中不太常见,在现代语言中,声明和定义往往结合在一起,但理解区别很有用,因为您的问题似乎主要与术语有关。
可以声明变量,但它们没有定义。
let b; // we declare that there's a variable 'b'
相反,您可以分配一个变量:
b = 5; // assignment
let c = 6; // declaration and assignment in one statement
绑定在计算机科学中的概念有many forms。例如,当您在代码中键入foo 时,绑定就是确定应该使用哪个变量/函数/类型/...的行为。在 JavaScript 中,这非常简单,但在某些语言中,它可能会变得很复杂(由于重载决议等原因)。
但是,当 MDN 谈论 let 绑定 时,我不相信这就是他们的意思。正如我们在上面看到的,我相信它是“let 声明和赋值”的简写。
无论如何,我不会太担心这个词。从您引用的段落中要理解的最重要一点是let 和const 是var 的更严格版本,在该语言的最新版本中引入以解决var 方式带来的陷阱和惊喜有效。
以前我认为变量关键字和变量名一起构成一个声明
你是对的。
var a;
var b = 1;
let c;
let c = 2;
const d = 3;
这些都是变量声明(尽管const 技术变量不能改变,或者更准确地说,它们不能被重新分配)。
只是var有点草率和意外。
您可以在同一范围内多次声明一个 var:
var a = 1;
var a = 2;
这不适用于let:
let a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared
var 的范围也可能令人惊讶:
for (var i = 0; i < 10; i++)
{
var inner = 1;
}
console.log(inner); // prints 1 even though you might think this would be an error
或者更糟:
for (var i = 0; i < 10; i++)
{
for (var i = 0; i < 10; i++)
{
console.log('hello');
}
}
乍一看你可能认为这会打印hello 100 次 (10*10),但实际上它只打印了 10 次,因为两个循环使用相同的变量。这是语言应该真正防止的一种程序员错误。如果该代码改用let i,则会产生语法错误。
至于提升,你可以把它想成好像所有的var 声明都被移到了包含函数的顶部。
function foo()
{
doThing();
var i = 0;
doSomethingElse();
for (var j = 0; j < 10; j++)
{
var k = 10;
}
}
即使您可能会这样编写代码,但它的行为就像您编写的一样:
function foo()
{
var i; // all declarations hoisted to top of containing function scope
var j;
var k;
doThing();
i = 0;
doSomethingElse();
for (j = 0; j < 10; j++)
{
k = 10;
}
}
这就是你可以写作的原因:
i = 10;
var i;
var 在代码中向上移动,因此它的行为如下:
var i;
i = 10;
你可以认为let 没有被移动。因此在声明之前引用它是错误的。