![](/img/trans.png)
[英]What does the at symbol (@) do in ES6 javascript? (ECMAScript 2015)
[英]What is the difference between 'let' and 'const' ECMAScript 2015 (ES6)?
我想知道ES6中的let
和const
有什么区别。 它们都是块作用域,如以下代码中的示例:
const PI = 3.14;
console.log(PI);
PI = 3;
console.log(PI);
const PI = 4;
console.log(PI);
var PI = 5;
console.log(PI);
在 ES5 中,输出将是:
3.14
3.14
3.14
3.14
但在 ES6 中它将是:
3.14
3
4
5
我想知道为什么ES6允许更改const
值,问题是为什么我们现在应该使用 'const' ? 我们可以改用“让”吗?
注意: jsbin可用于测试,选择JavaScript运行ES5代码, Traceur运行ES6能力。
let
和const
之间的区别在于,一旦使用const
将值/对象绑定到变量,就不能重新分配给该变量。 换句话说示例:
const something = {};
something = 10; // Error.
let somethingElse = {};
somethingElse = 1000; // This is fine.
问题细节声称这是对 ES5 的更改——这实际上是一种误解。 在只支持 ECMAScript 5 的浏览器中使用const
总是会抛出错误。 ECMAScript 5 中不存在const
语句。其中的行为要么是 JS Bin 误导了正在运行的 JavaScript 类型,要么是浏览器错误。
在实践中,浏览器并不是一次性从 0% 支持 ECMAScript 2015 (ECMAScript 6) 到 100% — 功能是逐位添加的,直到浏览器完全兼容。 JS Bin 所说的“JavaScript”只是指您的浏览器当前支持的任何 ECMAScript 功能——它并不意味着“ES5”或“ES6”或其他任何东西。 许多浏览器在完全支持 ES6 之前就支持const
和let
,但有些浏览器(如 Firefox)在一段时间内将const
视为let
。 提问者的浏览器很可能支持let
和const
但没有正确实现它们。
其次,像 Babel 和 Traceur 之类的工具不会让 ES6 在旧版浏览器中“运行”——而是将 ES6 代码转换为 ES5 做大致相同的事情。 Traceur 可能会将const
语句转换为var
语句,但我怀疑它总是强制const
语句的语义在 ES5 中完全复制。 使用 JS Bin 使用 Traceur 运行 ES6 不会得到与在完全符合 ES6 规范的浏览器中运行 ES6 完全相同的结果。
重要的是要注意const
不会使值或对象不可变。
const myArray = [];
myArray.push(1); // Works fine.
myArray[1] = 2; // Also works fine.
console.log(myArray); // [1, 2]
myArray = [1, 2, 3] // This will throw.
目前使对象(浅)不可变的最佳方法可能是在其上使用Object.freeze()
。 但是,这只会使对象本身成为只读的; 对象属性的值仍然可以改变。
您所看到的只是一个实施错误。 根据 const 上的const
规范 wiki , const
是:
一次初始化,此后只读绑定形式很有用,并且在现有实现中具有先例,以 const 声明的形式。
它是只读的,就像现在一样。 Traceur 和 Continuum 中const
的 ES6 实现有问题(他们可能只是忽略了它)
let 对于绝大多数代码都非常有用。 它可以大大提高您的代码可读性并减少编程错误的机会。
let abc = 0; if(true) abc = 5 //fine if(true){ let def = 5 } console.log(def)
const 在可读性和可维护性方面都是一个很好的做法,并且避免使用魔法文字,例如
// Low readability if (x > 10) { } //Better! const maxRows = 10; if (x > maxRows) { }
必须初始化 const 声明
const foo; // ERROR: const declarations must be initialized
- 一个 const 是块作用域,就像我们在 let:+ 中看到的那样
const foo = 123;
if (true) {
const foo = 456; // Allowed as its a new variable limited to this `if` block
}
let
和const
ES6 let
允许你声明一个范围限制在块中的变量(局部变量)。 主要区别在于var
变量的作用域是整个封闭函数:
if (true) {
var foo = 42; // scope globally
}
console.log(foo); // 42
let
范围if (true) {
let foo = 42; // scoped in block
}
console.log(foo); // ReferenceError: foo is not defined
在函数范围内使用var
与使用let
相同:
function bar() {
var foo = 42; // scoped in function
}
console.log(foo); // ReferenceError: foo is not defined
let
关键字将变量声明附加到它包含的任何块的范围内。
let
和var
之间的另一个区别是声明/初始化顺序。 在声明之前访问由let
声明的变量会导致ReferenceError 。
console.log(a); // undefined
console.log(b); // ReferenceError: b is not defined
var a = 1;
let b = 2;
const
另一方面,使用 ES6 的const
很像使用let
,但是一旦赋值,就不能改变了。 使用const
作为不可变值,以防止意外重新分配变量:
const num = 42;
try {
num = 99;
} catch(err) {
console.log(err);
// TypeError: invalid assignment to const `number'
}
num; // 42
使用const
分配现实生活中不变的变量(例如冷冻温度)。 JavaScript const
不是要制作不可更改的值,它与值无关, const
是为了防止为变量重新分配另一个值并使变量为只读。 但是,值总是可以改变的:
const arr = [0, 1, 2];
arr[3] = 3; // [0, 1, 2, 3]
要防止值更改,请使用Object.freeze()
:
let arr = Object.freeze([0, 1, 2]);
arr[0] = 5;
arr; // [0, 1, 2]
let
和For
循环 let
真正大放异彩的一个特殊情况是在for
循环的标头中:
for (let i = 0; i <= 5; i++) {
console.log(i);
}
// 0 1 2 3 4 5
console.log(i); // ReferenceError, great! i is not global
let
和const
关键字都是声明块作用域变量的方法。 但是有一个很大的区别:
let
声明的变量可以重新赋值。const
声明的变量必须在声明时进行初始化,并且不能重新分配。 如果您尝试重新分配使用const
关键字声明的变量,您将收到以下错误(chrome devtools):
如果我们知道要分配一次变量并且不想重新分配变量,则使用const
关键字具有以下优点:
const
声明的变量。 通过这种方式,我们的代码变得更具声明性并且更易于使用。 尽管用const
声明的变量不能重新分配,但这并不意味着分配的对象不可变。 例如:
const obj = {prop1: 1} // we can still mutate the object assigned to the // variable declared with the const keyword obj.prop1 = 10; obj.prop2 = 2; console.log(obj);
如果您还希望您的对象是不可变的,您可以使用Object.freeze()
来实现这一点。
让和常量
用let
和const
声明的变量消除了提升的特定问题,因为它们的作用域是块,而不是函数。
如果在代码块中使用let
或const
声明变量(用大括号 { } 表示),则该变量会停留在所谓的时间死区中,直到处理变量的声明。 这种行为会阻止变量在被声明之前被访问。
使用 let 和 const 的规则
let
和const
还有一些其他有趣的属性。
let
声明的变量可以重新赋值,但不能在同一范围内重新声明。const
声明的变量必须赋初值,但不能在同一作用域内重新声明,也不能重新赋值。用例
最大的问题是什么时候应该使用let
和const
? 一般经验法则如下:
let
,并且const
。 由于const
是声明变量的最严格方法,因此建议您始终使用const
声明变量,因为它会使您的代码更容易推理,因为您知道标识符在程序的整个生命周期内都不会改变。 如果您发现需要更新或更改变量,则返回并将其从const
切换为let
。
var 声明是全局作用域或函数作用域,而 let 和 const 是块作用域。
var 变量可以在其范围内更新和重新声明; let 变量可以更新但不能重新声明;const 变量不能更新也不能重新声明。
它们都被提升到了范围的顶部。 但是,虽然 var 变量是用 undefined 初始化的,但 let 和 const 变量不会被初始化。
虽然 var 和 let 可以在不初始化的情况下声明,但 const 必须在声明期间初始化。
以下是我记下的一些笔记,对我在这个问题上有所帮助。 还将const
和let
与var
进行比较。
这是关于var
:
// Var
// 1. var is hoisted to the top of the function, regardless of block
// 2. var can be defined as last line and will be hoisted to top of code block
// 3. for undefined var //output error is 'undefined' and code continues executing
// 4. trying to execute function with undefined variable
// Example: // log(myName); // output: ReferenceError: myName is not defined and code stops executing
这是关于let
和const
的:
// Let and Const
// 1. use `const` to declare variables which won't change
// 2. `const` is used to initialize-once, read-only thereafter
// 3. use `let` to declare variables which will change
// 4. `let` or `const` are scoped to the "block", not the function
// 5. trying to change value of const and then console.logging result will give error
// const ANSWER = 42;
// ANSWER = 3.14159;
// console.log(ANSWER);
// Error statement will be "TypeError: Assignment to constant variable." and code will stop executing
// 6. `let` won't allow reference before definition
// function letTest2 () {
// log(b);
// let b = 3;}
// Error statement will be "ReferenceError: b is not defined." and code will stop executing
变量
The var keyword was introduced with JavaScript.
It has global scope.
It can be declared globally and can be accessed globally.
Variable declared with var keyword can be re-declared and updated in the same scope.
Example:
function varGreeter(){
var a = 10;
var a = 20; //a is replaced
console.log(a);
}
varGreeter();
它被吊起。
Example:
{
console.log(c); // undefined.
//Due to hoisting
var c = 2;
}
让
The let keyword was added in ES6 (ES 2015) version of JavaScript.
It is limited to block scope.
It can be declared globally but cannot be accessed globally.
Variable declared with let keyword can be updated but not re-declared.
Example:
function varGreeter(){
let a = 10;
let a = 20; //SyntaxError:
//Identifier 'a' has already been declared
console.log(a);
}
varGreeter();
它没有被吊起。
Example:
{
console.log(b); // ReferenceError:
//b is not defined
let b = 3;
}
全局对象属性
var no1 = "123"; // globally scoped
let no2 = "789"; // globally scoped
console.log(window.no1); // 123
console.log(window.no2); // undefined
重新声明:
'使用严格';
var name= "Keshav";
var name= "Keshav Gera"; // No problem, 'name' is replaced.
let surname= "Rahul Kumar";
let surname= "Rahul Khan "; // SyntaxError: Identifier 'surname' has already been declared
吊装
function run() {
console.log(name); // undefined
var name= "Keshav";
console.log(name); // Keshav
}
run();
function checkHoisting() {
console.log(name); // ReferenceError
let name= "Keshav";
console.log(name); // Keshav
}
checkHoisting();
注意:如果是var,你会得到undefined,如果是let,你会得到reference error
常量
It allows you to be immutable with variables.
必须初始化 const 声明
const name; // ERROR: const declarations must be initialized
A const is block scoped like we saw with let:+
const num = 10;
if (true) {
const num = 20; // Allowed as its a new variable limited to this `if` block
}
/*
// declaration of const in same block scope is not allowed
const a = 10;
const a = 15; //Redeclaration of const a Error
console.log(`const outer value `+a);
*/
/*
//declaration of const in different block scope is allowed
const a = 10;
console.log(`outer value of a `+a)
{
const a = 15; //Redeclaration of const allowed in different block scope
console.log(`ineer value of a `+a);
}
*/
/*
// re assigning const variable in any block scope is not allowed
const a = 10;
a = 15; //invalid assignment to const 'a'
{
a = 15; //invalid assignment to const 'a'
}
*/
/*
// let also can not be re declared in the same block scope
let a = 10;
let a = 15; //SyntaxError: redeclaration of let a
*/
/*
// let can be redeclared in different block scope
let a = 10;
{
let a = 15; //allowed.
}
*/
/*
// let can be re assigned in same block or different block
let a = 10;
a = 15; //allowed for let but for const its not allowed.
*/
/*
let a = 10;
{
a = 15; //allowed
}
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.