導語:ES6是什么?用來做什么?
-
ES6, 全稱 ECMAScript 6.0 ,是 JavaScript 的下一個版本標準,2015.06 發版
-
雖然15年就有正式版本了,但是國內普遍商用是在2018年之后去了,甚至到現在有很多前端仍然搞不懂ES6(都2021年了,兄dei~)
-
ES6 的出現主要是為了解決 ES5 的先天不足,比如 JavaScript 里并沒有類的概念
-
目前存在少數低版本瀏覽器的 JavaScript 是 ES5 版本,大多數的瀏覽器已經支持 ES6
-
ES6提供了大量的語法糖,讓你寫代碼的時候簡直不要太爽!
-
你必須要知道的是:現在各企業都普遍使用,不會ES6意味著你很難找到工作,上班了你連別人的代碼都看不懂
1. let 與 const
1.1 let 與 var
-
let:ES6新增,用于聲明變量,有塊級作用域
-
var:ES5中用于聲明變量的關鍵字,存在各種問題(例如:紅杏出墻~)
-
如果你的代碼里還存在 var,那你的良心就大大的壞了!
var存在的問題:
console.log(name); var name = "大帥比"; var demo = "小明"; var demo = "小紅"; console.log(demo) function fn2(){ for(var i = 0; i < 5; i++){ } console.log(i); } fn2();
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
let不會存在上述問題:
console.log(name); let name = "大帥比"; let demo = "小明"; let demo = "小紅"; console.log(demo) function fn2(){ for(let i = 0; i < 5; i++){ } console.log(i); } fn2();
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
const
-
const 聲明一個只讀的常量,一旦聲明,常量的值就不能改變
-
一般用于全局變量
-
通常變量名全部大寫(請按照規則來,不要亂搞,容易出事情)
const PI = "3.1415926";
2. 解構賦值
-
解構賦值是對賦值運算符的擴展
-
針對數組或者對象進行模式匹配,然后對其中的變量進行賦值
-
代碼簡潔且易讀,語義更加清晰明了,方便了復雜對象中數據字段獲取(簡而言之:用起來很爽!)
2.1 用在數組上
let [a, b, c] = [1, 2, 3]; let arr = ["小明", "小花", "小魚", "小豬"]; let [,,one] = arr; let strArr = [...arr]; console.log(strArr);
2.2 用在對象上
let obj = { className : "卡西諾", age: 18 } let {className} = obj; let {age} = obj; let {a, b, ...demo} = {a: 1, b: 2, c: 3, d: 4};
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
3. 模板字符串
-
模板字符串相當于加強版的字符串,用反引號 ``
-
除了作為普通字符串,還可以用來定義多行字符串,可以在字符串中加入變量和表達式
3.1 普通字符串
let string = "hello"+"小兄弟"; let string = "hello'\n'小兄弟"
3.2 模板字符串
let str1 = "穿堂而過的"; let str2 = "風"; let newStr = `我是${str1}${str2}`; console.log(newStr) function fn3(){ return "帥的不行!"; } let string2= `我真是${fn3 ()}`; console.log(string2);
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
4. ES6 函數(升級后更爽)
4.1 箭頭函數
-
箭頭函數是一種更加簡潔的函數書寫方式
-
箭頭函數本身沒有作用域(無this)
-
箭頭函數的this指向上一層,上下文決定其this
-
基本語法:參數 => 函數體
a. 基本用法
let fn = v => v;
//等價于
let fn = function(num){
return num;
}
fn(100); // 輸出100
b. 帶參數的寫法
let fn2 = (num1,num2) => {
let result = num1 + num2;
return result;
}
fn2(3,2); // 輸出5
c. 箭頭函數中的this指向問題
-
箭頭函數體中的 this 對象,是定義函數時的對象,而不是使用函數時的對象。在函數定義的時候就已經決定了
function fn3(){
setTimeout(()=>{
// 定義時,this 綁定的是 fn3 中的 this 對象
console.log(this.a);
},0)
}
var a = 10;
// fn3 的 this 對象為 {a: 10},因為它指向全局: window.a
fn3.call({a: 18}); // 改變this指向,此時 a = 18
d. 箭頭函數適用的場景
-
當我們代碼里存在這樣的代碼:let self = this;
-
需要新建變量去保存this的時候
-
案例如下:
let Person1 = {
'age': 18,
'sayHello': function () {
setTimeout(()=>{
console.log(this.age);
});
}
};
var age = 20;
Person1.sayHello(); // 18
4.2 函數參數的擴展
1. 默認參數
function fn(type, num=10){ console.log(type, num); } fn(1); fn(1,2);
-
需要注意的是:只有在未傳遞參數,或者參數為 undefined 時,才會使用默認參數,null 值被認為是有效的值傳遞。
2. 不定參數
function f(...values){ console.log(values.length); } f(1,2); f(1,2,3,4);
5. Class類
-
class (類)作為對象的模板被引入,可以通過 class 關鍵字定義類
-
class 的本質是 function,同樣可以看成一個塊
-
可以看作一個語法糖,讓對象原型的寫法更加清晰
-
更加標準的面向對象編程語法
5.1 類的定義
let Demo = class { constructor(a) { this.a = a; } } let Demo = class Demo { constructor(a) { this.a = a; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
5.2 類的聲明
class Demo { constructor(a) { this.a = a; } }
-
請注意,類不能重復聲明
-
類定義不會被提升,必須在訪問前對類進行定義,否則就會報錯。
-
類中方法不需要 function 關鍵字。
-
方法間不能加分號
5.3 類的主體
class Demo{} Demo.prototype.a = 2;
class Demo { a = 2; constructor () { console.log(this.a); } }
class Demo{ constructor(){ console.log('我是構造器'); } } new Demo();
如果不寫constructor,也會默認添加
5.4 實例化對象
class Demo { constructor(a, b) { this.a = a; this.b = b; console.log('Demo'); } sum() { return this.a + this.b; } } let demo1 = new Demo(2, 1); let demo2 = new Demo(3, 1); console.log(demo1._proto_ == demo2._proto_); demo1._proto_.sub = function() { return this.a - this.b; } console.log(demo1.sub()); console.log(demo2.sub());
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
6. Map()
6.1 Maps 和 Objects 的區別
-
一個 Object 的鍵只能是字符串或者 Symbols,但一個 Map 的鍵可以是任意值
-
Map 中的鍵值是有序的(FIFO 原則),而添加到對象中的鍵則不是
-
Map 的鍵值對個數可以從 size 屬性獲取,而 Object 的鍵值對個數只能手動計算
6.2 Map中的key
let myMap = new Map(); let keyString = "string"; myMap.set(keyString, "和鍵'string'關聯的值"); myMap.get(keyString); myMap.get("string"); let myMap = new Map(); let keyObj = {}, myMap.set(keyObj, "和鍵 keyObj 關聯的值"); myMap.get(keyObj); myMap.get({});
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
6.3 Map 的迭代
let myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); myMap.forEach(function(value, key) { console.log(key + " = " + value); }, myMap)
6.4 Map 與 Array的轉換
letkvArray = [["key1", "value1"], ["key2", "value2"]]; let myMap = new Map(kvArray); let outArray = Array.from(myMap);
6.5 關于map的重點面試題
-
請談一下 Map和ForEach 的區別(問到map,必定問到此題)
詳細解析:
-
forEach()方法不會返回執行結果,而是undefined
-
map()方法會得到一個新的數組并返回
-
同樣的一組數組,map()的執行速度優于 forEach()(map() 底層做了深度優化)
性質決定了兩者應用場景的不同
-
forEach() 適合于你并不打算改變數據的時候,而只是想用數據做一些事情(比如存入數據庫)
let arr = ['a', 'b', 'c', 'd']; arr.forEach((val) => { console.log(val); });
-
map() 適用于你要改變數據值的時候,它更快,而且返回一個新的數組
let arr = [1, 2, 3, 4, 5]; let arr2 = arr.map(num => num * 2).filter(num => num > 5);