es6筆記

一、es6聲明變量的方式

var命令和function命令,let和const命令和import命令和class命令。

二、 es6頂層對象的屬性

ES6為規(guī)定,為了保持兼容性,var命令和function命令聲明的全局變量,依舊是頂層對象的屬性;
另一方面規(guī)定,let命令、const命令、class命令聲明的全局變量,不屬于頂層對象的屬性。也就是說,從ES6開始,全局變量將逐步與頂層對象的屬性脫鉤。

var a = 1;
// 如果在Node的REPL環(huán)境,可以寫成global.a
// 或者采用通用方法,寫成this.a
window.a // 1

let b = 1;
window.b // undefined
上面代碼中,全局變量a由var命令聲明,所以它是頂層對象的屬性;全局變量b由let命令聲明,所以它不是頂層對象的屬性,返回undefined。

三、es6數(shù)組的解構(gòu)賦值

1、完全解構(gòu)
var [a, b, c] = [1, 2, 3];
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
2、不完全解構(gòu)

另一種情況是不完全解構(gòu),即等號左邊的模式,只匹配一部分的等號右邊的數(shù)組。這種情況下,解構(gòu)依然可以成功。

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

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

如果等號的右邊不是數(shù)組(或者嚴格地說,不是可遍歷的結(jié)構(gòu),參見《Iterator》一章),那么將會報錯。

// 報錯
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
3、es6數(shù)組解構(gòu)賦值允許指定默認值。
var [foo = true] = [];
foo // true

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

注意,ES6內(nèi)部使用嚴格相等運算符(===),判斷一個位置是否有值。所以,如果一個數(shù)組成員不嚴格等于undefined,默認值是不會生效的。

默認值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明。

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

上面最后一個表達式之所以會報錯,是因為x用到默認值y時,y還沒有聲明。

四、es6對象的解構(gòu)賦值

1、解構(gòu)不僅可以用于數(shù)組,還可以用于對象。
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

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

如果變量名與屬性名不一致,必須寫成下面這樣。

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

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

這實際上說明,對象的解構(gòu)賦值是下面形式的簡寫(參見《對象的擴展》一章)。

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

也就是說,對象的解構(gòu)賦值的內(nèi)部機制,是先找到同名屬性,然后再賦給對應的變量。真正被賦值的是后者,而不是前者

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

面代碼中,foo是匹配的模式,baz才是變量。真正被賦值的是變量baz,而不是模式foo。

2、es6解構(gòu)也可以用于嵌套結(jié)構(gòu)的對象。

下面是嵌套賦值的例子。

let obj = {};
let arr = [];

({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });

obj // {prop:123}
arr // [true]
3、es6對象的解構(gòu)也可以指定默認值。
var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x:y = 3} = {};
y // 3

var {x:y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
4、es6默認值生效的條件

默認值生效的條件是,對象的屬性值嚴格等于undefined。

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null
5、如果要將一個已經(jīng)聲明的變量用于解構(gòu)賦值,必須非常小心。
// 錯誤的寫法
var x;
{x} = {x: 1};
// SyntaxError: syntax error

上面代碼的寫法會報錯,因為JavaScript引擎會將{x}理解成一個代碼塊,從而發(fā)生語法錯誤。只有不將大括號寫在行首,避免JavaScript將其解釋為代碼塊,才能解決這個問題。

/ 正確的寫法
({x} = {x: 1});

上面代碼將整個解構(gòu)賦值語句,放在一個圓括號里面,就可以正確執(zhí)行。

五、es6字符串解構(gòu)賦值

字符串也可以解構(gòu)賦值。這是因為此時,字符串被轉(zhuǎn)換成了一個類似數(shù)組的對象。

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

六、函數(shù)參數(shù)的解構(gòu)賦值

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

函數(shù)參數(shù)的解構(gòu)也可以使用默認值。

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]

七、es6字符串的擴展---新增的方法

1、for....of 遍歷器接口

ES6為字符串添加了遍歷器接口(詳見《Iterator》一章),使得字符串可以被for...of循環(huán)遍歷。

for (let codePoint of 'foo') {
  console.log(codePoint)
}
// "f"
// "o"
// "o"
2、確定一個字符串是否包含在另一個字符串中的方法

傳統(tǒng)上,JavaScript只有indexOf方法
ES6又提供了三種新方法。
includes():返回布爾值,表示是否找到了參數(shù)字符串。
startsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的頭部。
endsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的尾部。

var s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

這三個方法都支持第二個參數(shù),表示開始搜索的位置。

var s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

上面代碼表示,使用第二個參數(shù)n時,endsWith的行為與其他兩個方法有所不同。它針對前n個字符,而其他兩個方法針對從第n個位置直到字符串結(jié)束。

3、字符串的repeat()

repeat方法返回一個新字符串,表示將原字符串重復n次。

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

參數(shù)如果是小數(shù),會被取整。

'na'.repeat(2.9) // "nana"

八、RegExp構(gòu)造函數(shù)

在ES5中,RegExp構(gòu)造函數(shù)的參數(shù)有兩種情況。

第一種情況是,參數(shù)是字符串,這時第二個參數(shù)表示正則表達式的修飾符(flag)。

var regex = new RegExp('xyz', 'i');
// 等價于
var regex = /xyz/i;

但是,ES5不允許此時使用第二個參數(shù),添加修飾符,否則會報錯。

var regex = new RegExp(/xyz/, 'i');
// Uncaught TypeError: Cannot supply flags when constructing one RegExp from another

ES6改變了這種行為。如果RegExp構(gòu)造函數(shù)第一個參數(shù)是一個正則對象,那么可以使用第二個參數(shù)指定修飾符。而且,返回的正則表達式會忽略原有的正則表達式的修飾符,只使用新指定的修飾符。

new RegExp(/abc/ig, 'i').flags
// "i"

上面代碼中,原有正則對象的修飾符是ig,它會被第二個參數(shù)i覆蓋。

2、es6 RegExp新增了flags屬性
// ES5的source屬性
// 返回正則表達式的正文
/abc/ig.source
// "abc"
// ES6的flags屬性
// 返回正則表達式的修飾符
/abc/ig.flags
// 'gi'

九、ES6在Number對象上,新提供的方法。

Number.isFinite()用來檢查一個數(shù)值是否為有限的(finite)

Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false

Number.isNaN()用來檢查一個值是否為NaN。

Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true'/0) // true
Number.isNaN('true'/'true') // true

它們與傳統(tǒng)的全局方法isFinite()和isNaN()的區(qū)別在于,傳統(tǒng)方法先調(diào)用Number()將非數(shù)值的值轉(zhuǎn)為數(shù)值,再進行判斷,而這兩個新方法只對數(shù)值有效,非數(shù)值一律返回false。

isFinite(25) // true
isFinite("25") // true
Number.isFinite(25) // true
Number.isFinite("25") // false

isNaN(NaN) // true
isNaN("NaN") // true
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
2、es6數(shù)值的方法Number.parseInt(), Number.parseFloat()

ES6將全局方法parseInt()和parseFloat(),移植到Number對象上面,行為完全保持不變。

// ES5的寫法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45

// ES6的寫法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

這樣做的目的,是逐步減少全局性方法,使得語言逐步模塊化。

Number.parseInt === parseInt // true
Number.parseFloat === parseFloat // true
3、Number.isInteger()用來判斷一個值是否為整數(shù)
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
Number.isInteger("15") // false
Number.isInteger(true) // false

4、Math對象的擴展

ES6在Math對象上新增了17個與數(shù)學相關的方法。所有這些方法都是靜態(tài)方法,只能在Math對象上調(diào)用。
Math.trunc(),方法用于去除一個數(shù)的小數(shù)部分,返回整數(shù)部分。

Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0

對于非數(shù)值,Math.trunc內(nèi)部使用Number方法將其先轉(zhuǎn)為數(shù)值。

Math.trunc('123.456')
// 123

對于空值和無法截取整數(shù)的值,返回NaN。

Math.trunc(NaN);      // NaN
Math.trunc('foo');    // NaN
Math.trunc();         // NaN

十、ES6 數(shù)組的擴展

1、Array.from()

下面是一個類似數(shù)組的對象,Array.from將它轉(zhuǎn)為真正的數(shù)組。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES5的寫法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的寫法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

Array.from還可以接受第二個參數(shù),作用類似于數(shù)組的map方法,用來對每個元素進行處理,將處理后的值放入返回的數(shù)組。

Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
3、Array.of()方法用于將一組值,轉(zhuǎn)換為數(shù)組。
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
4、數(shù)組實例的find()和findIndex()

數(shù)組實例的find方法,用于找出第一個符合條件的數(shù)組成員。它的參數(shù)是一個回調(diào)函數(shù),所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù),直到找出第一個返回值為true的成員,然后返回該成員。如果沒有符合條件的成員,則返回undefined。

[1, 4, -5, 10].find((n) => n < 0)
// -5
[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10

上面代碼中,find方法的回調(diào)函數(shù)可以接受三個參數(shù),依次為當前的值、當前的位置和原數(shù)組。

4、數(shù)組實例的entries(),keys()和values()

ES6提供三個新的方法——entries(),keys()和values()——用于遍歷數(shù)組。它們都返回一個遍歷器對象(詳見《Iterator》一章),可以用for...of循環(huán)進行遍歷,唯一的區(qū)別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Bable的Es6 2 Es5工具 let與const let let聲明的變量只在它所在的代碼塊有效。 let聲...
    jh2k15閱讀 300評論 0 0
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,915評論 0 1
  • 一. let 和 const 1 let 基本用法 ES6新增let命令,與var用法類似,但所聲明的變量只在聲明...
    dodomix閱讀 2,365評論 0 2
  • ES6 箭頭函數(shù)(lambda表達式)(agr) => { 函數(shù)體 }注:只有一個參數(shù)可以省略(),函數(shù)體為一個表...
    神刀閱讀 265評論 0 0
  • 剛剛,我聽到朋友訴說的委屈。我對于現(xiàn)如今傳統(tǒng)媒體表示堪憂,作為一個媒體最基本的底線是確定事件證據(jù)無誤后,在發(fā)表任何...
    憤青少年閱讀 934評論 0 2

友情鏈接更多精彩內(nèi)容