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中原始資料型別:Symbol
、undefined
、null
、Boolean
、String
、Number
、Object
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的鍵名所指向的物件,不計入垃圾回收機制。
好吧,暫時先到這兒。另外一部分後面繼續整理吧~知識點還是蠻多的。