1. 程式人生 > >ES6 學習筆記(上)

ES6 學習筆記(上)

認真學習了一遍ES6,發現很多很好用的功能。
學習資料:《ECMAScript 6 入門》

之前寫JS,雖然也遇到一些ES6語法,基本就是理解就行,沒有深入學習過。這次認真看了一遍ES6,發現裡面有許多實用的東西。下面是對本書學習的一些筆記

let 和 const 命令

解決var變數提升、變數全域性的問題。

let 和 const 都只作用域本塊級作用域內。

let a = 123
{
    let a = 456
    console.log(a)
}
console.log(a)

// 456
// 123

let 和 const 定義的變數不能同名。
let 和 const 定義的變數不可以變數提升。

a = 5
let a

// Error: a is not defined

const定義的量記憶體不可變

const a = 6
const obj = {
    name: 'violetjack'
}

// 以下寫法會報錯,因為他們指向了另一個記憶體地址
// a = 6
// obj = {}

obj.name = 'jerry'
obj.age = 56
console.log(obj)

// { name: 'jerry', age: 56 }

變數的結構與賦值

快速賦值,優化程式碼可讀性。

用法都差不多,一一對應即可

let [a, b, c] = [1, 2
, 3] // 陣列結構 let { name:mName, age: mAge} = { name:'violetjack', age: 28 } // 物件結構 let [e,f,g] = 'mmp' // 字串結構 console.log(a) console.log(mName) console.log(e + f + g) // 1 // violetjack // mmp

字串擴充套件

提出了一些處理字串的方式

提供了一些處理大於 0xFFFF 的字串的方法
字串檢索

let s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith
('!') // true s.includes('o') // true // includes():返回布林值,表示是否找到了引數字串。 // startsWith():返回布林值,表示引數字串是否在原字串的頭部。 // endsWith():返回布林值,表示引數字串是否在原字串的尾部。

可以操作複製、填充字串:repeat,padStart,padEnd
模板字串,解決字串拼接問題。

const name = 'VioletJack'
const str = 'welcome to ' + name + "'s blog"
const str2 = `welcome to ${name}'s blog`
console.log(str)
console.log(str2)

// welcome to VioletJack's blog
// welcome to VioletJack's blog

相比於第一種方式,第二種方式可讀性好很多。也避免了在使用 ' " 兩個符號的時候需要轉譯的步驟。同時在引用資料上使用 ${value} 的方式引用。非常方便!

正則的擴充套件

對於正則我一向暈暈乎乎,沒啥收穫。關於正則我要另外寫篇部落格漲漲姿勢。

數值的擴充套件

主要提供了一些數字高階演算法。
parseInt和parseFloat都在Number中呼叫,減少js中的全域性方法。

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

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

求指數,通過 ** 實現

2 ** 2 // 2*2 = 4
2 ** 3 // 2*2*2 = 8

其他數學演算法就不一一列舉了,基本用不著,用到了百度即可。

函式的擴充套件

在函式引數傳遞方面實現了更多傳遞方式,實現了箭頭函式。總體上是讓函式應用上ES6的結構、rest 引數。此外還有幾個提案,可以去書上看看。

更多的引數傳遞方式

// 函式引數預設值
function func01(a, b = 11) {
    console.log(a + b)
}

func01(15)
func01(10, undefined)
func01(1, 1)

// 引數解構
function func02({a = 6, b}) {
    console.log(a + b)
}

func02({a: 11, b: 12})
func02({b: 6})

// rest引數
function func03(...vals) {
    let count = 0
    for (let value of vals) {
        count += value
    }
    console.log(count)
}

func03(1, 2, 3, 4, 5)
func03(11, 22, 33, 44, 55)

提出箭頭函式,簡化程式碼。

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;
};

注意如果引數或者返回結果是物件,需要用()包裹。

var fun = ({ a, b }) => a + b
var fun02 = a => ({ value: a })

另外一個特別要注意的就是 this,我看到過好幾篇部落格來解釋箭頭函式的 this 的,可見這個 this 的特殊性。可以在掘金搜尋箭頭函式,裡面全是解釋(tu cao)箭頭函式的~
下面搬運書上對箭頭函式的注意點。

箭頭函式有幾個使用注意點。
(1)函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。
(2)不可以當作建構函式,也就是說,不可以使用new命令,否則會丟擲一個錯誤。
(3)不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用 rest 引數代替。
(4)不可以使用yield命令,因此箭頭函式不能用作 Generator 函式。
上面四點中,第一點尤其值得注意。this物件的指向是可變的,但是在箭頭函式中,它是固定的。

陣列的擴充套件

擴充套件運算子,和函式中的rest引數是一回事。我的理解就是把陣列拆分成一個個值。

let arr = [1, 2, 3, 4]
console.log(...arr)
console.log([0, 8, 6, ...arr, 10])
let str = 'jack'
console.log(...str)

// 1 2 3 4
// [ 0, 8, 6, 1, 2, 3, 4, 10 ]
// j a c k

Array.from 將類陣列物件轉為真正的陣列。
Array.of 將多個值轉為陣列

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

copyWithin 將陣列中某些內容來替換指定內容
find 和 findIndex 用於找到陣列中第一個符合條件的值和索引位置。

var a = [1, 4, -5, 10].find((n) => n < 2)
console.log(a)
var b = [1, 5, 10, 15].findIndex(function (value, index, arr) {
    return value > 11;
}) 
console.log(b)

// 1
// 3

fill 用於填充陣列
entries、keys和values用來遍歷陣列非常方便,通過不同方法返回所需陣列內容。

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"

includes 方法與字串的 includes 類似,用於查詢陣列中是否有某個值,返回布林型別的值。
ES6中將陣列空位轉為undefined

console.log([...['a',,'b']])
// [ "a", undefined, "b" ]

物件的擴充套件

物件屬性的簡潔表示法,也就是我們常看到的ES6的寫法。物件中不再必須要傳遞 key-value 的形式了。

let a = 12
let b = 22
let obj = { a, b }
console.log(obj)

// { a: 12. b: 22 }

let obj02 = {
    log() {
        console.log('Hello!')
    }
}

對於物件屬性名,支援使用 [字串] 的形式來作為物件屬性名。

let obj = {
    name: 'jack',
    ['age']: 28,
    ['se' + 'x']: 'male'
}
console.log(obj)

// {name: "jack", age: 28, sex: "male"}

Object.is方法用於比較兩個值是否嚴格相等。
Object.assign 用於物件的合併,如果有同名屬性,後新增的覆蓋之前的屬性。

let obj1 = {
    name: 'jack'
}

let obj2 = {
    ['age']: 28,
    ['se' + 'x']: 'male'
}

let obj3 = {
    job: 'js'
}

let obj4 = {
    name: 'rose',
    hobby: 'game'
}

Object.assign(obj1, obj2, obj3, obj4)
console.log(obj1)

// {name: "rose", age: 28, sex: "male", job: "js", hobby: "game"}

物件的_proto_屬性是一個內部屬性,所以前後有下劃線。不建議修改該屬性。
ES6的super關鍵字用於繼承,可以理解為java的super關鍵字。
Object.keys(),Object.values(),Object.entries()和Array的類似,是對物件的一個遍歷過程。

let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };

for (let key of keys(obj)) {
  console.log(key); // 'a', 'b', 'c'
}

for (let value of values(obj)) {
  console.log(value); // 1, 2, 3
}

for (let [key, value] of entries(obj)) {
  console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}

在物件中也可以使用擴充套件運算子 ...

Symbol

這玩意的用處我不太理解,就是為了表示一個唯一的值?
ES6 的7中原始資料型別:SymbolundefinednullBooleanStringNumberObject

Set 和 Map 資料結構

Set是一個建構函式,它的值都是唯一的。

const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
  console.log(i);
}
// 2 3 5 4

Set可用於去除陣列中的重複項。

const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

操作Set的語法如下

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

WeakSet與Set的不同點

WeakSet 的成員只能是物件,而不能是其他型別的值。
WeakSet 中的物件都是弱引用,即垃圾回收機制不考慮 WeakSet 對該物件的引用,也就是說,如果其他物件都不再引用該物件,那麼垃圾回收機制會自動回收該物件所佔用的記憶體,不考慮該物件還存在於 WeakSet 之中。

Map不同於傳統Object物件的地方在於,Object的屬性名只能是String型別的。而Map可以有任意型別的屬性名。
Map的key如果是一個物件,那麼這個key應該指向同一個記憶體(可以用const定義之後再當做引數傳入map作為屬性名。)。

// error
const map = new Map();

map.set(['a'], 555);
map.get(['a']) // undefined

// success
const map = new Map();

const k1 = ['a'];
const k2 = ['a'];

map
.set(k1, 111)
.set(k2, 222);

map.get(k1) // 111
map.get(k2) // 222

WeakMap與Map的區別:

WeakMap只接受物件作為鍵名(null除外),不接受其他型別的值作為鍵名。
WeakMap的鍵名所指向的物件,不計入垃圾回收機制。

好吧,暫時先到這兒。另外一部分後面繼續整理吧~知識點還是蠻多的。