抹桥的博客
Language
Home
Archive
About
GitHub
Language
主题色
250
1350 words
7 minutes
ECMAScript 6 Learning Notes (Part 1) - Variable Declaration, String Extensions, Number Extensions

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 and function commands are properties of the global object; however, global variables declared with let, const, and class 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 be undefined. This is because primitive values are automatically converted to objects (e.g., the number 1 becomes new Number(1)), which then causes foo to receive undefined.

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.

ECMAScript 6 Learning Notes (Part 1) - Variable Declaration, String Extensions, Number Extensions
https://blog.kisnows.com/en-US/2015/08/21/learning-ecmascript6-one/
Author
Kisnows
Published at
2015-08-21
License
CC BY-NC-ND 4.0