JavaScript學習筆記(十九)ES6
阿新 • • 發佈:2020-12-30
ES6新增的內容
- 之前的都是 ES5 的內容
- 接下來我們聊一下 ES6 的內容
let 和 const 關鍵字
- 我們以前都是使用 var 關鍵字來宣告變數的
- 在 ES6 的時候,多了兩個關鍵字 let 和 const,也是用來宣告變數的
- 只不過和 var 有一些區別
1、let 和 const 不允許重複宣告變數
// 使用 var 的時候重複宣告變數是沒問題的,只不過就是後面會把前面覆蓋掉
var num = 100
var num = 200
// 使用 let 重複宣告變數的時候就會報錯了 let num = 100 let num = 200 // 這裡就會報錯了 // 使用 const 重複宣告變數的時候就會報錯 const num = 100 const num = 200 // 這裡就會報錯了
2、let 和 const 宣告的變數不會在預解析的時候解析(也就是沒有變數提升)
// 因為預解析(變數提升)的原因,在前面是有這個變數的,只不過沒有賦值
console.log(num) // undefined
var num = 100
// 因為 let 不會進行預解析(變數提升),所以直接報錯了
console.log(num) // undefined
let num = 100
// 因為 const 不會進行預解析(變數提升),所以直接報錯了
console.log(num) // undefined
const num = 100
3、let 和 const 宣告的變數會被所有程式碼塊限制作用範圍
// var 宣告的變數只有函式能限制其作用域,其他的不能限制
if (true) {
var num = 100
}
console.log(num) // 100
// let 宣告的變數,除了函式可以限制,所有的程式碼塊都可以限制其作用域(if/while/for/...)
if (true) {
let num = 100
console.log(num) // 100
}
console.log(num) // 報錯
// const 宣告的變數,除了函式可以限制,所有的程式碼塊都可以限制其作用域(if/while/for/...) if (true) { const num = 100 console.log(num) // 100 } console.log(num) // 報錯
- let 和 const 的區別
1、let 宣告的變數的值可以改變,const 宣告的變數的值不可以改變
let num = 100
num = 200
console.log(num) // 200
const num = 100
num = 200 // 這裡就會報錯了,因為 const 宣告的變數值不可以改變(我們也叫做常量)
2、let 宣告的時候可以不賦值,const 宣告的時候必須賦值
let num
num = 100
console.log(num) // 100
const num // 這裡就會報錯了,因為 const 宣告的時候必須賦值
箭頭函式
- 箭頭函式是 ES6 裡面一個簡寫函式的語法方式
- 重點:箭頭函式只能簡寫函式表示式,不能簡寫宣告式函式
function fn() {} // 不能簡寫
const fun = function () {} // 可以簡寫
const obj = {
fn: function () {} // 可以簡寫
}
- 語法: (函式的行參) => { 函式體內要執行的程式碼 }
const fn = function (a, b) {
console.log(a)
console.log(b)
}
// 可以使用箭頭函式寫成
const fun = (a, b) => {
console.log(a)
console.log(b)
}
const obj = {
fn: function (a, b) {
console.log(a)
console.log(b)
}
}
// 可以使用箭頭函式寫成
const obj2 = {
fn: (a, b) => {
console.log(a)
console.log(b)
}
}
箭頭函式的特殊性
- 箭頭函式內部沒有 this,箭頭函式的 this 是上下文的 this
// 在箭頭函式定義的位置往上數,這一行是可以打印出 this 的
// 因為這裡的 this 是 window
// 所以箭頭函式內部的 this 就是 window
const obj = {
fn: function () {
console.log(this)
},
// 這個位置是箭頭函式的上一行,但是不能打印出 this
fun: () => {
// 箭頭函式內部的 this 是書寫箭頭函式的上一行一個可以打印出 this 的位置
console.log(this)
}
}
obj.fn()
obj.fun()
- 按照我們之前的 this 指向來判斷,兩個都應該指向 obj
- 但是 fun 因為是箭頭函式,所以 this 不指向 obj,而是指向 fun 的外層,就是 window
- 箭頭函式內部沒有 arguments 這個引數集合
const obj = {
fn: function () {
console.log(arguments)
},
fun: () => {
console.log(arguments)
}
}
obj.fn(1, 2, 3) // 會列印一個偽陣列 [1, 2, 3]
obj.fun(1, 2, 3) // 會直接報錯
- 函式的行參只有一個的時候可以不寫 () 其餘情況必須寫
const obj = {
fn: () => {
console.log('沒有引數,必須寫小括號')
},
fn2: a => {
console.log('一個行參,可以不寫小括號')
},
fn3: (a, b) => {
console.log('兩個或兩個以上引數,必須寫小括號')
}
}
- 函式體只有一行程式碼的時候,可以不寫 {} ,並且會自動 return
const obj = {
fn: a => {
return a + 10
},
fun: a => a + 10
}
console.log(fn(10)) // 20
console.log(fun(10)) // 20
函式傳遞引數的時候的預設值
- 我們在定義函式的時候,有的時候需要一個預設值出現
- 就是當我不傳遞引數的時候,使用預設值,傳遞引數了就使用傳遞的引數
function fn(a) {
a = a || 10
console.log(a)
}
fn() // 不傳遞引數的時候,函式內部的 a 就是 10
fn(20) // 傳遞了引數 20 的時候,函式內部的 a 就是 20
- 在 ES6 中我們可以直接把預設值寫在函式的行參位置
function fn(a = 10) {
console.log(a)
}
fn() // 不傳遞引數的時候,函式內部的 a 就是 10
fn(20) // 傳遞了引數 20 的時候,函式內部的 a 就是 20
- 這個預設值的方式箭頭函式也可以使用
const fn = (a = 10) => {
console.log(a)
}
fn() // 不傳遞引數的時候,函式內部的 a 就是 10
fn(20) // 傳遞了引數 20 的時候,函式內部的 a 就是 20
- 注意:箭頭函式如果你需要使用預設值的話,那麼一個引數的時候也需要寫 ()
解構賦值
- 解構賦值,就是快速的從物件或者陣列中取出成員的一個語法方式
解構物件
- 快速的從物件中獲取成員
// ES5 的方法向得到物件中的成員
const obj = {
name: 'Jack',
age: 18,
gender: '男'
}
let name = obj.name
let age = obj.age
let gender = obj.gender
// 解構賦值的方式從物件中獲取成員
const obj = {
name: 'Jack',
age: 18,
gender: '男'
}
// 前面的 {} 表示我要從 obj 這個物件中獲取成員了
// name age gender 都得是 obj 中有的成員
// obj 必須是一個物件
let { name, age, gender } = obj
解構陣列
- 快速的從陣列中獲取成員
// ES5 的方式從陣列中獲取成員
const arr = ['Jack', 'Rose', 'Tom']
let a = arr[0]
let b = arr[1]
let c = arr[2]
// 使用解構賦值的方式從陣列中獲取成員
const arr = ['Jack', 'Rose', 'Tom']
// 前面的 [] 表示要從 arr 這個陣列中獲取成員了
// a b c 分別對應這陣列中的索引 0 1 2
// arr 必須是一個數組
let [a, b, c] = arr
注意
- {} 是專門解構物件使用的
- [] 是專門解構陣列使用的
- 不能混用
模版字串
- ES5 中我們表示字串的時候使用 '' 或者 ""
- 在 ES6 中,我們還有一個東西可以表示字串,就是``(反引號)
let str = `hello world`
console.log(typeof str) // string
- 和單引號好友雙引號的區別
1、反引號可以換行書寫
// 這個單引號或者雙引號不能換行,換行就會報錯了
let str = 'hello world'
// 下面這個就報錯了
let str2 = 'hello
world'
let str = `
hello
world
`
console.log(str) // 是可以使用的
2、反引號可以直接在字串裡面拼接變數
// ES5 需要字串拼接變數的時候
let num = 100
let str = 'hello' + num + 'world' + num
console.log(str) // hello100world100
// 直接寫在字串裡面不好使
let str2 = 'hellonumworldnum'
console.log(str2) // hellonumworldnum
// 模版字串拼接變數
let num = 100
let str = `hello${num}world${num}`
console.log(str) // hello100world100
在``裡面的 ${} 就是用來書寫變數的位置
展開運算子
- ES6 裡面號新添加了一個運算子 ... ,叫做展開運算子
- 作用是把陣列展開
let arr = [1, 2, 3, 4, 5]
console.log(...arr) // 1 2 3 4 5
- 合併陣列的時候可以使用
let arr = [1, 2, 3, 4]
let arr2 = [...arr, 5]
console.log(arr2)
- 也可以合併物件使用
let obj = {
name: 'Jack',
age: 18
}
let obj2 = {
...obj,
gender: '男'
}
console.log(obj2)
- 在函式傳遞引數的時候也可以使用
let arr = [1, 2, 3]
function fn(a, b, c) {
console.log(a)
console.log(b)
console.log(c)
}
fn(...arr)
// 等價於 fn(1, 2, 3)
Map 和 Set
- 是 ES6 新增的兩個資料型別
- 都是屬於內建建構函式
- 使用 new 的方式來例項化使用
Set
- 使用方式就是和 new 連用
const s = new Set()
console.log(s)
/*
Set(0) {}
size: (...)
__proto__: Set
[[Entries]]: Array(0)
length: 0
*/
- 就是一個數據集合
- 我們可以在 new 的時候直接向內部新增資料
// 例項化的時候直接新增資料要以陣列的形式新增
const s = new Set([1, 2, 3, {}, function () {}, true, 'hwllo'])
console.log(s)
/*
Set(7) {1, 2, 3, {…}, ƒ, …}
size: (...)
__proto__: Set
[[Entries]]: Array(7)
0: 1
1: 2
2: 3
3: Object
4: function () {}
5: true
6: "hwllo"
length: 7
*/
- 看上去是一個類似陣列的資料結構,但是不是,就是Set 資料結構
常用方法和屬性
- size : 用來獲取該資料結構中有多少資料的
const s = new Set([1, 2, 3, {}, function () {}, true, 'hwllo'])
console.log(s.size) // 7
看上去是一個和陣列資料型別差不多的資料結構,而且我們也看到了 length 屬性
但是不能使用,想要獲取該資料型別中的成員數量,需要使用 size 屬性
- add : 用來向該資料型別中追加資料
const s = new Set()
s.add(0)
s.add({})
s.add(function () {})
console.log(s.size) // 3
這個方法就是向該資料型別中追加資料使用的
- delete : 是刪除該資料結構中的某一個數據
const s = new Set()
s.add(0)
s.add({})
s.add(function () {})
s.delete(0)
console.log(s.size) // 2
- clear : 清空資料結構中的所有資料
const s = new Set()
s.add(0)
s.add({})
s.add(function () {})
s.clear()
console.log(s.size) // 0
- has : 查詢資料解構中有沒有某一個數據
const s = new Set()
s.add(0)
s.add({})
s.add(function () {})
console.log(s.has(0)) // true
- forEach : 用來遍歷 Set 資料結構的方法
const s = new Set()
s.add(0)
s.add({})
s.add(function () {})
s.forEach(item => {
console.log(item) // 0 {} function () {}
})
- 方法介紹的差不多了,有一個問題出現了,那就是
- 我們的方法要麼是新增,要麼是刪除,要麼是查詢,沒有獲取
- 因為要獲取 Set 結構裡面的資料需要藉助一個 ... 展開運算子
- 把他裡面的東西都放到一個數組裡面去,然後再獲取
const s = new Set([1, 2, 3, 4, 5, 6])
const a = [...s]
console.log(a) // (6) [1, 2, 3, 4, 5, 6]
console.log(a[0]) // 1
console.log([...s][0]) // 1
- 又一個問題出現了,new 的時候需要以陣列的形式傳遞
- 然後獲取的時候又要轉成陣列的形式獲取
- 那麼我為什麼不一開始就定義陣列,要這個 Set 資料型別幹什麼
- 這就不得不提到一個 Set 的特點
- Set 不允許儲存重複的資料
const s = new Set([1, 2, 3])
s.add(4) // 此時 size 是 4
s.add(1) // 此時 size 是 4
s.add(2) // 此時 size 是 4
s.add(3) // 此時 size 是 4
Map
- 也是要和 new 連用
- 是一個數據集合,是一個很類似於 物件 的資料集合
const m = new Map()
console.log(m)
/*
Map(0) {}
size: (...)
__proto__: Map
[[Entries]]: Array(0)
length: 0
*/
- 我們的物件中不管儲存什麼,key 一定是一個字串型別
- 但是再 Map 裡面,我們的 key 可以為任意資料型別
- 我們也管 Map 叫做 (值 = 值 的資料型別)
const m = new Map([[{}, {}], [function () {}, function () {}], [true, 1]])
console.log(m)
/*
Map(3) {{…} => {…}, ƒ => ƒ, true => 1}
size: (...)
__proto__: Map
[[Entries]]: Array(3)
0: {Object => Object}
key: {}
value: {}
1: {function () {} => function () {}}
key: ƒ ()
value: ƒ ()
2: {true => 1}
key: true
value: 1
length: 3
*/
常用方法和屬性
- size : 用來獲取該資料型別中資料的個數
const m = new Map([[{}, {}], [function () {}, function () {}], [true, 1]])
console.log(m.size) // 3
- delete : 用來刪除該資料集合中的某一個數據
const m = new Map([[{}, {}], [function () {}, function () {}], [true, 1]])
m.delete(true)
console.log(m.size) // 2
- set : 用來向該資料集合中新增資料使用
const m = new Map()
m.set({ name: 'Jack' }, { age: 18 })
console.log(m.size) // 1
- get : 用來獲取該資料集合中的某一個數據
const m = new Map()
m.set({ name: 'Jack' }, { age: 18 })
m.set(true, function () {})
console.log(m.get(true)) // function () {}
- clear : 清除資料集合中的所有資料
const m = new Map()
m.set({ name: 'Jack' }, { age: 18 })
m.set(true, function () {})
m.clear()
console.log(m.size) // 0
- has : 用來判斷資料集合中是否存在某一個數據
const m = new Map()
m.set({ name: 'Jack' }, { age: 18 })
m.set(true, function () {})
console.log(m.has(true)) // true