let
and const
Commands
The let
Command
Variables declared with let
exist only within the code block where they are declared.
{
let a = 10;
var b = 11;
}
console.log(a); //ReferenceError: a is not defined
console.log(b); //11
As you can see, variables declared with let
cannot be accessed outside their code block. This means let
declarations are block-scoped, which helps avoid certain variable declaration issues.
var arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {}
console.log(i); //ReferenceError: a is not defined
It’s clear from the code above that the variable i
cannot be accessed outside the for
loop.
In contrast, the following code, declared with var
, will output 10.
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
However, if let
is used, it will output 6. Previously, achieving this might have required an immediately invoked function expression (IIFE).
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
Furthermore, let
does not exhibit ‘hoisting’ like var
.
function a(){
console.log(b) //ReferenceError
let b = 2;
}
function c(){
console.log(d); //undefined
var d = 2;
Within a block scope, variables declared with let
are bound to that specific region and are not affected by external scopes.
var temp = 123;
let temp1 = 222;
var temp2 = 555;
if (true) {
let temp = 333;
let temp1 = 444;
console.log(temp); //333
console.log(temp1); //444
console.log(temp2); //ReferenceError
let temp2 = 555;
}
let
does not allow redeclaring the same variable within the same scope.
function(){
let a = 10;
var a = 1;
}
function(){
let a = 11;
let a = 212;
}
The const
Command
const
is similar to let
, except that variables declared with const
are constants and cannot be reassigned once declared.
const a = 1;
a; //1
a = 3;
a; //1
const a = 12;
a; //1
It’s important to note that const
only points to the memory address where the variable is stored. Therefore, special care is needed when declaring objects as constants.
const foo = {};
foo.prop = 1;
foo.prop; //1
const a = [];
a.push("Hello"); // 可执行
a.length = 0; // 可执行
a = ["Dave"]; // 报错
In the code above, the constant
foo
stores an address that points to an object. What is immutable is only this address; that is,foo
cannot be reassigned to point to another address. However, the object itself is mutable, so new properties can still be added to it.
This means that when an object or array is declared as a constant, the variable itself cannot be reassigned, but you can still add properties or methods to the object/array. This is because only its memory address remains constant.
Properties of the Global Object
ES6 specifies that global variables declared with
var
andfunction
commands are properties of the global object; however, global variables declared withlet
,const
, andclass
commands are not properties of the global object.
var a = 1;
// 如果在node环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a; // 1
let b = 1;
window.b; // undefined
Destructuring Assignment for Variables
ES6 allows extracting values from arrays and objects according to certain patterns and assigning them to variables. This is called destructuring. It feels quite similar to Python’s approach.
Array Destructuring Assignment
var [a, b] = [1, 2];
console.log(a, b);
//1 2
let [c, d] = [3, 4];
console.log(c, d);
//3 4
In essence, it’s a form of ‘pattern matching.’ As long as the patterns on both sides of the assignment operator are identical, the variables on the left will be assigned their corresponding values.
var [a, b, [c, d]] = [1, 2, [3, 4]];
//a = 1,b = 2,c = 3,d = 4
var [aa, bb, cc] = [, , 3];
//aa = undefined,bb = undefined,cc = 3;
let [one, ...more] = [1, 2, 3, 4, 5, 6];
//one = 1,more = [2,3,4,5,6]
As seen in the code above, as long as their structures match, the variables on the left at corresponding positions will be assigned the respective values from the right. If there’s no corresponding value, it will be undefined
.
The following scenarios result in unsuccessful destructuring, leading to a TypeError
, and the variable’s value will be undefined
.
In all the above cases, destructuring fails, and the value of
foo
will beundefined
. This is because primitive values are automatically converted to objects (e.g., the number 1 becomesnew Number(1)
), which then causesfoo
to receiveundefined
.
var [foo] = [];
var [foo] = 1;
var [foo] = false;
var [foo] = NaN;
var [bar, foo] = [1];
let [foo] = undefined;
let [foo] = null;
Destructuring assignment allows specifying default values. A default value takes effect when an array member is strictly equal to undefined
.
var [foo = true] = [];
foo[(x, (y = "b"))] = // true
["a"][(x, (y = "b"))] = // x='a', y='b'
["a", undefined][(x, (y = "b"))] =
// x='a', y='b'
[1, null]; // x= 1,y=null
Object Destructuring Assignment
Destructuring also applies to objects. The difference from arrays is that array elements are accessed by their position, whereas object properties have no inherent order, so the variable name must match the property name to retrieve the correct value.
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo; // "aaa"
bar; // "bbb"
//注意两者区别
var { foo, bar } = { bar: "aaa", foo: "bbb" };
foo; // "bbb"
bar; // "aaa"
var { fos } = { foo: "aaa" };
fos; // undefined
As seen in the code above, assignment is solely based on the property name, not the order. If the property name doesn’t match, the value will be undefined
.
If you need to assign a value when the variable name and property name differ, you can use the following method.
var { foo: abs } = { foo: "sss" };
abs; // 'sss'
Objects with nested structures can also be destructured.
let obj = {
p: ["Hello", { y: "World" }],
};
let {
p: [x, { y }],
} = obj;
console.log(x, y);
//Hello World
Similar to arrays, object destructuring also allows specifying default values. A default value will be used if the corresponding object property to be assigned is strictly equal to undefined
.
var { a = 3 } = {};
a; //3
var { b = 4, y } = { y: 4 };
(b, y); //4,4
Object destructuring assignment provides significant convenience.
var obj = {
method1: function () {},
method2: function () {},
};
var { method1, method2 } = obj;
//以前的写法
var method1 = obj.method1;
var method2 = obj.method2;
String Destructuring Assignment
Strings can also be destructured. During destructuring, a string is converted into an array-like object.
let [f, g, h] = "length";
console.log(f, g, h);
//l,e,n
let { length: len } = "length";
console.log(len);
//6
Function Parameter Destructuring Assignment
Function parameters are array-like objects and can also be destructured.
function a([x, y]) {
return x + y;
}
add([1, 2]); //3
Default values can also be set.
function move({x=0,y=0}={}){
"use strict";
console.log([x,y]);
}
move({x:3,y:4}); //[3,4]
move({x:3}); //[3,0]
move({}); //[0,0]
move(); //[0,0]
function remove({x,y}={x:0,y:0}){
"use strict";
console.log(x,y);
}
remove({x:1,y:2}); //1,2
remove({x,y}); //Hello World
remove({}); //undefined undefined
remove(); // 0 0
The destructuring method for function parameters is automatically chosen based on the parameter type: array destructuring for arrays, and object destructuring for objects.
function fc([x,y,z]){
"use strict";
console.log(x,y,z);
}
fc([1,2,3]); //1,2,3
function nf({x,y,z}){
"use strict";
console.log(x,y,z);
}
nf({y:1,z:2,x:3}); //3,1,2
Use Cases
Extracting JSON Data
var jsonDate = {
id: 42,
status: "notOK",
data: [12, 32],
};
let { id, status, data } = jsonDate;
console.log(id, status, data); //42 'notOK' [12,32]
Iterating Map Structures
var map = new Map();
map.set("first", "HELLO");
map.set("second", "WORLD");
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is HELLO
// second is WORLD
for (let key of map) {
console.log(key);
}
//['first','HELLO']
//[ 'second', 'WORLD' ]
Copyright
All code in this article is sourced from or adapted from:
Ruan Yi-feng - ECMAScript 6 入门 (Getting Started with ECMAScript 6), This article also follows the Attribution-NonCommercial License.
This article was published on August 21, 2015 and last updated on August 21, 2015, 3698 days ago. The content may be outdated.