ES6 筆記(未完)

一. let 和 const

1 let

基本用法

ES6新增let命令,與var用法類似,但所聲明的變量只在聲明的代碼塊中使用

{
    let a=10;
    var b=1;
}
a//a is not defined

b//1

var 聲明的變量像是 static 的

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // a[1]->a[10]的值都是10
var a = [];
for (let i = 0; i < 10; i++) {//變量 i 使用 let 聲明只在本輪循環有效,每次循環 值都是一個新的變量
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6
a[5]();//5

不存在變量提升

let 聲明的變量一定要在聲明后使用,否則報錯

console.log(foo); // 輸出undefined,foo 在此時已經存在
console.log(bar); // 報錯ReferenceError

var foo = 2;
let bar = 2;

temporal dead zone

只要塊級作用于存在letconst命令, 凡是在聲明之前使用這些變量就會報錯

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError: tmp is not defined
  let tmp;
}

不允許重復聲明

//let不允許在相同作用域內,重復聲明同一個變量。

// 報錯
function () {
  let a = 10;
  var a = 1;
}

// 報錯
function () {
  let a = 10;
  let a = 1;
}
//因此,不能在函數內部重新聲明參數。d[s

function func(arg) {
  let arg; // 報錯
}

function func(arg) {
  {
    let arg; // 不報錯
  }
}

2 塊級作用域

為什么需要塊級作用域?

第一種場景,內層變量可能會覆蓋外層變量。

var tmp = new Date();

function f(){
  console.log(tmp);
  if (false){
    var tmp = "hello world";
  }
}

f() // undefined  內層的tmp變量覆蓋了外層的tmp變量。

第二種場景,用來計數的循環變量泄露為全局變量。

var s = 'hello';

for (var i = 0; i < s.length; i++){
  console.log(s[i]);
}

console.log(i); // 5

ES6的塊級作用域

let實際上為JavaScript新增了塊級作用域。

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
      console.log(n); // 10

  }
  console.log(n); // 5
}


{
  let a = 'secret';
  function f() {
    return a;
  }
}
f() // 報錯
//上面代碼中,塊級作用域外部,無法調用塊級作用域內部定義的函數。如果確實需要調用,就要像下面這樣處理。

let f;
{
  let a = 'secret';
  f = function () {
    return a;
  }
}
f() // "secret"

3 const 命令

const 聲明常量,類似于 java 中的 final,聲明后無法修改其值

'use strict';
const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: "PI" is read-only

//常規模式下不會報錯,但是修改無效
const PI = 3.1415;
PI = 3; // 常規模式時,重新賦值無效,但不報錯
PI // 3.1415

const 聲明的變量不得改變值, const 一旦聲明變量則需要給其賦值,不能在后面賦值,這點與 java 不同.

'use strict';
const foo;
// SyntaxError: missing = in const declaration

const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

不可重復聲明

var message = "Hello!";
let age = 25;

// 以下兩行都會報錯
const message = "Goodbye!";
const age = 30;

將對象聲明為常量,特性與 java 一樣

const foo = {};
foo.prop = 123;

foo.prop
// 123

foo = {} // TypeError: "foo" is read-only

const a = [];
a.push("Hello"); // 可執行
a.length = 0;    // 可執行
a = ["Dave"];    // 報錯

如果想將對象凍結,使用Object.freeze方法

const foo = Object.freeze({});

// 常規模式時,下面一行不起作用;
// 嚴格模式時,該行會報錯
foo.prop = 123;

4 跨模塊常量

// constants.js 模塊
export const A = 1;
export const B = 3;
export const C = 4;

// test1.js 模塊
import * as constants from './constants';
console.log(constants.A); // 1
console.log(constants.B); // 3

// test2.js 模塊
import {A, B} from './constants';
console.log(A); // 1
console.log(B); // 3

5 全局對象屬性

全局對象是最頂層的對象,在瀏覽器環境指的是window對象,在Node.js指的是global對象。ES5之中,全局對象的屬性與全局變量是等價的。

二. 變量的解構賦值

ES6允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。

1 數組的解構賦值

//以前,為變量賦值,只能直接指定值。

var a = 1;
var b = 2;
var c = 3;

//ES6允許寫成下面這樣。
var [a, b, c] = [1, 2, 3];

只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

對于Set結構,也可以使用數組的解構賦值。

let [x, y, z] = new Set(["a", "b", "c"])
x // "a"

結構賦值允許指定默認值

var [foo = true] = [];
foo // true

[x, y = 'b'] = ['a'] // x='a', y='b'
[x, y = 'b'] = ['a', undefined] // x='a', y='b'

惰性賦值,在用到的時候才會求值

function f(){
  console.log('aaa');
}

let [x = f()] = [1];

//經過babel翻譯后的代碼

var _ = 1;
var x = _ === undefined ? f() : _;

默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError

2. 對象的解構賦值(重要!!)

與數組不同的是,對象屬性沒有次序,變量必須與屬性同名才能取到正確值


var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

///相對應下面代碼

var _foo$bar = { foo: "aaa", bar: "bbb" };
var bar = _foo$bar.bar;
var foo = _foo$bar.foo;


var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

let { log, sin, cos } = Math;
/////////
var log = Math.log;
var sin = Math.sin;
var cos = Math.cos;

變量可以重命名


var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
////
var _foo$bar = { foo: "aaa", bar: "bbb" };
var baz = _foo$bar.foo;


let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
//////////
var obj = { first: 'hello', last: 'world' };
var f = obj.first;
var l = obj.last;

3. 函數參數的解構賦值


function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]


////--轉義后--

function move() {
  var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

  var _ref$x = _ref.x;
  var x = _ref$x === undefined ? 0 : _ref$x;
  var _ref$y = _ref.y;
  var y = _ref$y === undefined ? 0 : _ref$y;

  return [x, y];
}

另一種寫法

function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
////////
function move() {
  var _ref = arguments.length <= 0 || arguments[0] === undefined ? { x: 0, y: 0 } : arguments[0];

  var x = _ref.x;
  var y = _ref.y;

  return [x, y];
}

6.其他解構

字符串解構

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

let {length : len} = 'hello';
len // 5

數值解構

let {toString: s} = 123;
//////

var _ = 123;
var s = _.toString;

7 用途

交換變量值

[x, y] = [y, x];
/////
var _ref2 = [y, x];
x = _ref2[0];
y = _ref2[1];

函數返回多個值

// 返回一個數組

function example() {
  return [1, 2, 3];
}
var [a, b, c] = example();

// 返回一個對象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
var { foo, bar } = example();

函數參數定義


// 參數是一組有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3])

// 參數是一組無次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1})

提取Json數據

var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
}

let { id, status, data: number } = jsonData;

console.log(id, status, number)
// 42, "OK", [867, 5309]

//////
var id = jsonData.id;
var status = jsonData.status;
var number = jsonData.data;

遍歷MAP結構


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

模塊導入

const { SourceMapConsumer, SourceNode } = require("source-map");

三. 類型

ECMAScript 有 5 種原始類型,即 Undefined、Null、Boolean、Number 和 String。

1. Undefined

如前所述,Undefined 類型只有一個值,即 undefined。當聲明的變量未初始化時,該變量的默認值是undefined

2. Null

Null 類型只有一個值null ,值 undefined 實際上是從值 null 派生來的

null == undefined;//true
null === undefined;//false

3. Number

八進制數和十六進制數,ES5 之后八進制用0o表示

var iNum = 0o70;  //070 等于十進制的 56
var iNum = 0x1f;  //0x1f 等于十進制的 31

如果要將0b和0x前綴的字符串數值轉為十進制,要使用Number方法。

Number('0b111')  // 7
Number('0o10')  // 8

4. String

5. 類型轉換

轉換成字符串 toString() 方法

arrayObject.toString()
booleanObject.toString()
dateObject.toString()
NumberObject.toString()
stringObject.toString()

轉換成數字parseInt() 、 parseFloat()


var iNum1 = parseInt("12345red");   //返回 12345
var iNum1 = parseInt("0xA");    //返回 10
var iNum1 = parseInt("56.9");   //返回 56
var iNum1 = parseInt("red");    //返回 NaN

var fNum1 = parseFloat("12345red"); //返回 12345
var fNum2 = parseFloat("0xA");  //返回 NaN
var fNum3 = parseFloat("11.2"); //返回 11.2
var fNum4 = parseFloat("11.22.33"); //返回 11.22
var fNum5 = parseFloat("0102"); //返回 102
var fNum1 = parseFloat("red");  //返回 NaN

6.強制類型轉換

ECMAScript 中可用的 3 種強制類型轉換如下:

  • Boolean(value) - 把給定的值轉換成 Boolean 型;
  • Number(value) - 把給定的值轉換成數字(可以是整數或浮點數);
  • String(value) - 把給定的值轉換成字符串;

四. 數組

1. Array.from()

Array.from方法用于將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象(包括ES6新增的數據結構Set和Map)所謂類似數組的對象,本質特征只有一點,即必須有length屬性,因此,任何有length屬性的對象,都可以通過Array.from方法轉為數組。

Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']

let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']


...運算符也可以將某些結構轉換成數組

function foo() {
  var args = [...arguments];
}
////////

function foo() {
    var args = [].concat(_slice.call(arguments));
}


var t=[..."helloworld"] //["h","e","l","l","o","w","o","r","l","d"]

Array.from還可以接受第二個參數,用來對每個元素進行處理,將處理后的值放入返回的數組。

Array.from(arrayLike, x => x * x);
///////
Array.from(arrayLike, function (x) {
    return x * x;
});


Array.from([1, 2, 3], (x) => x * x)// [1, 4, 9]

////////
Array.from([1, 2, 3], function (x) {
    return x * x;
});

2. Array.of()

Array.of方法用于將一組值,轉換為數組。


Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

//Array.of方法可以用下面的代碼模擬實現。

function ArrayOf(){
  return [].slice.call(arguments);
}

3. find() findIndex()

find方法用于找出第一個符合條件的數組成員,參數是一個回調函數

[1, 4, -5, 10].find((n) => n < 0)//-5
/////

[1, 4, -5, 10].find(function (n) {
 return n < 0;
});


[1, 5, 10, 15].find(function(value, index, arr) {//依次為當前的值、當前的位置和原數組。
 return value > 9;
}) // 10

findIndex方法用于返回符合條件值的位置,如果沒有符合的返回-1


[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

5. fill()

填充數組

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

6. includes()

用來檢測數組里是否包含某個值

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, NaN].includes(NaN); // true

7. 數組推導

使用現有數組生成新數組


var a1 = [1, 2, 3, 4];
var a2 = [for (i of a1) i * 2];

a2 // [2, 4, 6, 8]
 
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];

[for (year of years) if (year > 2000) year];
// [ 2006, 2010, 2014 ]

[for (year of years) if (year > 2000) if(year < 2010) year];
// [ 2006]

[for (year of years) if (year > 2000 && year < 2010) year];
// [ 2006]


[for (i of [1, 2, 3]) i * i];
// 等價于
[1, 2, 3].map(function (i) { return i * i });

[for (i of [1,4,2,3,-8]) if (i < 3) i];
// 等價于
[1,4,2,3,-8].filter(function(i) { return i < 3 });

五. 函數

1. 參數默認值

ES6可以為函數參數設置默認值

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello


function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
}

var p = new Point();
p // { x: 0, y: 0 }

可以結合解構賦值使用


function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property 'x' of undefined

function fetch(url, { body = '', method = 'GET', headers = {} }){
  console.log(method);
}

fetch('http://example.com', {})
// "GET"

fetch('http://example.com')
// 報錯

上面這種寫法不能省略第二個參數,如果給第二個參數默認值則可以省略

function fetch(url, { method = 'GET' } = {}){
  console.log(method);
}

fetch('http://example.com')
// "GET"

需注意的情況

// 寫法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 寫法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}




// 函數沒有參數的情況
m1() // [0, 0]
m2() // [0, 0]

// x和y都有值的情況
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

// x有值,y無值的情況
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

// x和y都無值的情況
m1({}) // [0, 0];
m2({}) // [undefined, undefined]

m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]


參數默認值的位置

非尾部參數設置默認值,這個參數是無法省略的

function f(x = 1, y) {
  return [x, y];
}
///////
function f(x, y) {
  if (x === undefined) x = 1;

  return [x, y];
}


f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 報錯,其實本身這種語法就是錯誤的
f(undefined, 1) // [1, 1]

function f(x, y = 5, z) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報錯
f(1, undefined, 2) // [1, 5, 2]

函數的length屬性

指定了默認值以后,函數的length屬性,將返回沒有指定默認值的參數個數

(function(a){}).length // 1
(function(a = 5){}).length // 0
(function(a, b, c = 5){}).length // 2

默認值參數作用域

總結起來就是參數使用的變量已經生成則作用域是函數作用域否則更上層的作用域的變量已經生成則使用的是上層作用域的值,如果全局內都沒有此變量存在則會報錯

情況1:

var x = 1;

function f(x, y = x) {
  console.log(y);
}

f(2) // 2

情況2:

let x = 1;

function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // 1

情況3:


function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // ReferenceError: x is not defined

2. rest參數

就是...變量名形式的參數,表示不定數量的參數

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

rest參數后不能再有其他參數


// 報錯
function f(a, ...b, c) {
  // ...
}

注意函數的length屬性不包括rest參數

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

3. 擴展運算符(spread)

擴展運算符用...表示,用于將一個數組轉換為逗號分隔的參數序列。

console.log(...[1, 2, 3])//console.log(1,2,3)
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

主要用于函數調用

//多么扭曲的例子=_=
function f(v, w, x, y, z) { }
var args = [0, 1];
f(-1, ...args, 2, ...[3]);

替代apply方法

// ES5的寫法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f.apply(null, args);

// ES6的寫法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f(...args);

// ES5的寫法
Math.max.apply(null, [14, 3, 77])

// ES6的寫法
Math.max(...[14, 3, 77])

// 等同于
Math.max(14, 3, 77);

合并數組

// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]

var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];

// ES5的合并數組
arr1.concat(arr2, arr3));
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6的合并數組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

擴展解構賦值

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]

const [first, ...rest] = [];
first // undefined
rest  // []:

const [first, ...rest] = ["foo"];
first  // "foo"
rest   // []

需要注意的是將擴展運算符用于數組賦值則只能放在參數最后一位,否則會報錯


const [...butLast, last] = [1, 2, 3, 4, 5];
// 報錯

const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 報錯

map set結構

let map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

let arr = [...map.keys()]; // [1, 2, 3]

4. name屬性

用于返回該函數的函數名

var func1 = function () {};

// ES5
func1.name // ""

// ES6
func1.name // "func1"

5.箭頭函數

es6可以使用=>定義函數, => 左邊代表參數名

var f=v=>v;

///等價于///

var f = function(v) {
  return v;
};

如果箭頭函數不需要參數或者需要多個參數,使用括號代表參數部分

var f = () => 5;
// 等同于
var f = function (){ return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

如果方法體多于一行,則需要用{}并使用return 返回

var sum = (num1, num2) => { return num1 + num2; }

///////
var sum = function sum(num1, num2) {
  return num1 + num2;
};

如果箭頭部分直接返回對象,則必須在對象外邊加上括號

var getTempItem = id => ({id:id,name:"Temp"});
///////
var getTempItem = function getTempItem(id) {
  return { id: id, name: "Temp" };
};

6. 函數綁定

函數綁定運算符是::,雙冒號左邊是對象,右邊是一個函數,運算符會自動將左邊的對象作為上下文環境,綁定到右邊的函數上


foo::bar;
// 等同于
bar.bind(foo);

foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);

const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
  return obj::hasOwnProperty(key);
}

如果雙冒號左邊為空,右邊是一個對象的方法,則等于將該方法綁定在該對象上面。

var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;

let log = ::console.log;
// 等同于
var log = console.log.bind(console);

7. 尾調用優化

尾調用(Tail Call)是函數式編程的一個重要概念,就是指某個函數的最后一步是調用另一個函數。

function f(x){
  return g(x);
}

尾調用優化即只保留內層函數的調用幀.

如下例子,g函數調用后f就結束,則在最后執行g的時候f可以不用保留

function f() {
  let m = 1;
  let n = 2;
  return g(m + n);
}
f();

// 等同于
function f() {
  return g(3);
}
f();

// 等同于
g(3);

尾遞歸

通過尾調用優化可以節省尾遞歸產生的棧內存


function factorial(n, total) {
  if (n === 1) return total;
  return factorial(n - 1, n * total);
}

factorial(5, 1) // 120

尾調用優化只在嚴格模式下開啟

六. 對象

七. Proxy和Reflect

八. Set和Map數據結構

1. Set

初始化

var s = new Set();

var set = new Set([1, 2, 3, 4, 4])



添加數據

var s = new Set();

s.add(1);

兩個對象總是不相等的。

let set = new Set();

set.add({})
set.size // 1

set.add({})
set.size // 2

操作方法:

  • add(value):添加某個值,返回Set結構本身。
  • delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
  • has(value):返回一個布爾值,表示該值是否為Set的成員。
  • clear():清除所有成員,沒有返回值。

s.add(1).add(2).add(2);
// 注意2被加入了兩次

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false

遍歷操作:

  • keys():返回一個鍵名的遍歷器
  • values():返回一個鍵值的遍歷器
  • entries():返回一個鍵值對的遍歷器
  • forEach():使用回調函數遍歷每個成員
let set = new Set(['red', 'green', 'blue']);

for ( let item of set.keys() ){
  console.log(item);
}
// red
// green
// blue

for ( let item of set.values() ){
  console.log(item);
}
// red
// green
// blue

for ( let item of set.entries() ){
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

2. Map

初始化


var m = new Map();
var o = {p: "Hello World"};

m.set(o, "content")
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false


var map = new Map([["name", "張三"], ["title", "Author"]]);

map.size // 2
map.has("name") // true
map.get("name") // "張三"
map.has("title") // true
map.get("title") // "Author"

操作方法

  • size屬性: 返回Map成員總數
  • set(key, value):設置key所對應的鍵值
  • get(key):讀取key對應的鍵值如果找不到key,返回undefined
  • has(key):返回一個布爾值,表示某個鍵是否在Map數據結構中
  • delete(key):刪除某個鍵,返回true。如果刪除失敗,返回false
  • clear():方法清除所有成員,沒有返回值

遍歷方法

  • keys():返回鍵名的遍歷器。
  • values():返回鍵值的遍歷器。
  • entries():返回所有成員的遍歷器。
  • forEach():遍歷Map的所有成員。
let map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"

for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}

與其他結構互轉(TODO:)

九. Class

十. 異步

JS 是單線程模型的,在瀏覽器環境下 JS和其他瀏覽器任務共享同一個線程,在一個任務執行過程中會阻塞其他任務.

我們不能阻塞主線程太長時間,異步就是用來解決這種情況的.

常見的異步編程有以下四種:

  • 回調函數
  • 事件監聽
  • 發布/訂閱
  • Promise 對象

1. 回調函數

2. 事件監聽

在瀏覽器下的 js 編程中我們經常會寫到這樣的事件監聽代碼


var image1=document.querySelector('.img-1');

image1.addEventListener('load',()={
//圖片加載完成
});

image1.addEventListener('error',()=>{
//出現錯誤
})

3. 發布/訂閱

4. Promise(重要!!)

Promise 是異步編程的一種解決方案

4.1 基本用法

生成 Promise 實例

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise 構造函數接受一個函數作為參數,該函數有兩個參數resolvereject.這兩個函數由 JS 引擎提供不用自己部署.

resolve函數作用是將 Promise 對象的狀態從未完成(Pending)變成成功(Reolved)在異步操作成功時調用,并將異步操作的結果,作為參數傳遞出去;reject函數的作用是,將Promise對象的狀態未完變為失敗,在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去。

Promise實例生成以后,可以用then方法分別指定Resolved狀態和Reject狀態的回調函數。

promise.then(function(value) {
  // success
}, function(value) {
  // failure
});
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 官方中文版原文鏈接 感謝社區中各位的大力支持,譯者再次奉上一點點福利:阿里云產品券,享受所有官網優惠,并抽取幸運大...
    HetfieldJoe閱讀 3,046評論 3 37
  • 《ECMAScript6 入門》阮一峰 讀書筆記 let和constlet聲明的變量僅在塊級作用域內有效,var聲...
    親愛的孟良閱讀 746評論 1 2
  • 三,字符串擴展 3.1 Unicode表示法 ES6 做出了改進,只要將碼點放入大括號,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,576評論 0 8
  • 1 認識他是在微博 ,因為那時候是高二升高三的那個暑假,所以每天沒事就會刷刷微博,看看學習方法。因為學習,就認識他...
    默默的小獅子閱讀 590評論 0 2
  • 昨天晚上,有一位共事的伙伴要走了,走之前要去吃頓“散伙飯”。通常這樣的聚餐,我心里是五味雜陳,去與不去心里都難受。...
    九月雛菊閱讀 797評論 0 16