簡單說說 ES6 新特性
ECMAScript 6.0(以下簡稱 ES6)是 JavaScript 語言的下一代標準,已經在 2015 年 6 月正式發佈了。它的目標,是使得 JavaScript 語言可以用來編寫複雜的大型應用程序,成爲企業級開發語言。
ECMAScript 和 JS 的關係 ECMAScript 是標準, JS 是實現
-
類似於 HTML5 是標準, IE,chrome 是實現 例如國家定了醫用口罩標準
(需要過濾 XX,等等各種參數),咱們買的正規口罩是實現
-
目前 ECMAScript 除了 JS 還沒別的實現,所以 ECMAScript==JS 也說得
過去
-
ES6 發佈於 2015 年發佈, 所以也可以叫 es2015 去年的 ES2021 是 ES12
但是主要的改變是在 es6, 這幾年的東西都增加的不多,所以把 ES6 以及
以後的版本統稱爲 es6 也合理,ES2022 也也即將推出
今天對我目前所知的並且常用的一些做一個總結,適合處於新手村和即將走出新手村的兄弟觀看學習,同時也歡迎各位大佬補充
1、聲明變量
首先說說在沒有 es6 之前存在的問題,也就是 var 的問題
-
可以重複定義
-
無法限制修改,有些東西不會變化,沒常量
-
沒有塊級作用域,只有函數作用域
-
變量提示帶來的混亂
es6 新增了兩個聲明變量關鍵字,let 和 const 這兩個關鍵字就是爲了解決 es5 存在的問題
let
(1)let 聲明變量時只在其塊級作用域中有效
1 {
2 let a = 10;
3 var b = 1;
4 }
5 console.log(a); //出錯 not defined
6 console.log(b); //1
在 es5 中如果要實現塊級作用域,通常藉助立即執行匿名函數來實現
1 (function(){
2 var a = 1;
3 }());
4 console.log(a); //出錯,not defined
但是有了 let 之後,就可以解決這麼問題
(2)沒有變量提升
也正是如此,變量必須在聲明後使用,否則就會報錯,這裏對比 var 經典的變量提升
//let
console.log(a); //出錯, not defined
let a = 1;
//var
console.log(a); //undefined
var a =1;
(3)不可以在相同作用域內重複聲明同一個變量,也包括不能和 var,const 變量名重複
let a = 1;
let a = 1; //出錯 let不可重複聲明
var b = 1;
let b = 1; //出錯 let不可重複聲明
const c = 1;
let c = 1; //出錯 let不可重複聲明
(4)在塊級作用域內,若存在用 let 命令聲明的變量,則所在區塊對該變量形成封閉作用域,也就是該變量無視外部的同名變量。而又因爲不存在變量提升,所以在該區塊中,不能在聲明前使用該變量。
var a = 1;
if(true){
a = 2; //出錯 not defined
let a;
}
var a = 1;
if(true){
a = 2; //var允許重複聲明,而且變量提升,故a=2正常賦值
var a;
}
const
const 和 let 的區別在於 const 聲明的變量不能修改,let 聲明的變量可以修改
const name = "🐻";
//name = '2' //報錯
//但是也不是都不能變
const person = {
name:"🐻"
}
person.name="🐕";
console.log(person)
//const實際上保證的,並不是變量的值不得改動,
而是變量指向的那個內存地址所保存的數據不得改動。
//對於簡單類型的數據(數值、字符串、布爾值),
值就保存在變量指向的那個內存地址,因此等同於常量。
//但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,
保存的只是一個指向實際數據的指針,
//const只能保證這個指針是固定的(即總是指向另一個固定的地址),
//至於它指向的數據結構是不是可變的,就完全不能控制了。因此,
將一個對象聲明爲常量必須非常小心。
```js
學會之後推薦聲明變量時使用 let,可以避免很多不必要的麻煩,const 看個人需求
## **2、Symbol**
ES6 新增了一個基本數據類型:Symbol,至此 ECMAScript 的基本數據類型就有了 6 種:字符串,數字,布爾,null,undefined,Symbol。
```js
//Symbol 的定義不能使用new 他使用Symbol()函數生成
let a = Symbol();
typeof a // "symbol"
//Symbol創建時可以傳一個參數,表示對Symbol的描述
let s1 = Symbol('a');
let s2 = Symbol('b');
s1 // Symbol(a)
s2 // Symbol(b)
Symbol 表示獨一無二的值
1 let s1 = Symbol('a');
2 let s2 = Symbol('a');
3
4 //s1===s2 false;
5 //既然Symbol的值都不相等
那麼可以利用他的特性解決對象裏同名覆蓋的問題
6
7 let obj = {
8 [Symbol()]: 1
9 };
10 //或者
11 let s = Symbol();
12 let obj = {
13 [s]: 1
14 };
Symbol.for() 有時,我們希望重新使用同一個 Symbol 值,Symbol.for() 方法可以做到這一點。它接受一個字符串作爲參數,然後搜索有沒有以該參數作爲名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建一個以該字符串爲名稱的 Symbol 值,並將其註冊到全局。
1 let s1 = Symbol.for('a');
2 let s2 = Symbol.for('a');
3
4 s1 === s2 // true
5
6 //兩種寫法區別
7 Symbol.for("a") === Symbol.for("a") // true
8
9 Symbol("a") === Symbol("a") //false
## 3、解構賦值(常用)
1 let [a,b,c] = [1,2,3]
2 var [a,,c]=[1,2,3];
3 console.log(a+' | '+c); //1 | 3
4 var [a,...b]=[1,2,3];
5 console.log(a+' | '+b);//1 | 2,3
6 console.log(b);//[2, 3]
7 // ...將右側多餘的值以數組的形式賦值給左側變量
rest
8
9 //設置默認值
10 var [a,b,c='default',d='default']=[1,2,3];
11 console.log(a+' | '+b+' | '+c+' | '+d);
//1 | 2 | 3 | default
12
13 //找不到的會被賦值爲undefined
14 var [a,b,c]=[1,2];
15 console.log(a+' | '+b+' | '+c);
//1 | 2 | undefined
對象的解構賦值
1 //對象的解構賦值
2
3 let obj={
4 a:1,
5 b:2
6 }
7 let {a,b}=obj;
8 console.log(a+" | "+b);//1 | 2
9
10 //重命名,把obj.a重命名爲A
11 let obj={
12 a:1,
13 b:2
14 }
15 let {a:A,b}=obj;
16 console.log(A+" | "+b);//1 | 2
17 console.log(a);
//Uncaught ReferenceError: a is not defined
18
19 //設置默認值
20
21 let {a=1,b=2}={a:10};
22 console.log(a+" | "+b);//10 | 2
23
24 //字符串也可以解構
25
26 var [a,b,c,d,e]='nihao';
27 console.log(a);//
## 4、函數默認值
1 //es5寫法
2 function sum(a,b){
3 b= b||0;
4 console.log(a+b)
5 }
6
7 sum(1)
8
9 //es6
10 function sum(a,b=0){
11 console.log(a+b)
12 }
13 sum(1)
14 function sum(a=2,b=0){
15 console.log(a+b)
16 }
17
18 sum()
## 5、箭頭函數(常用)
箭頭函數都是匿名函數
1 function show(num){
2 return num*num
3 }
4 var show = function(num){
5
6 return num*num
7 }
8
9 //如果箭頭函數不需要參數或需要多個參數,
就使用一個圓括號代表參數部分。提個參數可以去掉括號
10 var show =(num)=>{
11 return num*num
12 }
13 //如果只有一條return語句,可以省略大括號和return
隱式返回
14
15 var show =num=>num*num;
16
17
18
19 //箭頭函數的this繼承自他的父作用域
20 //而且與我們原來普通函數不同,
原來的函數this是調用時動態指定的,
21 //而箭頭函數是詞法作用域,他裏的this是定義時就指定的
而且不會隨着調用方式不同而改變
22
23 //如下例子
24 var log_this = ()=>{
25
26 console.log(this)
27 }
28 var log_this = function(){
29
30 console.log(this)
31 }
32
33 var obj = {
34 hobbies:['code','run','paly game'],
35 logHobbies:log_this
36 }
37
38
39 obj.logHobbies()
40
41
42 log_this()
有幾點需要注意
-
函數體內的 this 對象,就是定義時所在的對象,而不是使用時所在的對象。
-
不可以當作構造函數,也就是說,不可以使用 new 命令,否則會拋出一個錯誤。
-
不可以使用 arguments 對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。
-
不可以使用 yield 命令,因此箭頭函數不能用作 Generator 函數。
- 上面四點中,第一點尤其值得注意。this 對象的指向是可變的,但是在箭頭函數中,它是固定的。
## 6、模板字符串(常用)
原來寫字符串比較痛苦 特別是拼接變量時
1 const name="小🐻";
2 const age = 2;
3
4 console.log('ta的名字是'+name+',它今年'+age+'了');
5 console.log
('<div data-age="'+age+'">'+name+'</div>');
//這種更難受
6 console.log(`ta的名字是${name},它今年${age}了`)
7 console.log(`<div data-age="${age}">${name}
8 </div>`)
模板字符串可以嵌套
1 var arr = [{
2 name:"蘋果",
3 price:11
4 },{
5 name:"香蕉",
6 price:12
7 }];
8
9
10 var template = `
11 <ul>
12 ${arr.map(v=>`
13 <li>${v.name}
14 <span>${v.price}</span>
15 </li>
16 `).join('')}
17 </ul>
18 `
19
20 console.log(template)
21
22 document.body.innerHTML = template;
## 7、數組
spread 展開運算符也是三個點(...)。它好比 rest 參數的逆運算,將一個數組轉爲用逗號分隔的參數序列。
1 const a = [1, 2, 3];
2 const b = [4,5,6];
3 const c = [...a] // [1,2,3]
4 //輕鬆拼接兩個數組
5 const d = [...a,...b] // [1,2,3,4,5,6]
6
7
8 //類數組對象變成數組
9 var list=document.getElementsByTagName('a');
10 var arr=[...list];
其實不單單是參數可以展開,對於對象和字符串同樣可以展開
1 const obj1 = { a: 111, b: 222 };
2 const obj2 = { c: 333, d: 444 };
3 const merged = { ...obj1, ...obj2 };
4 console.log(merged); // ->
{ a: 111, b: 222, c: 333, d: 444 }
5 //或者這樣
6 const others = {third: 3, fourth: 4, fifth: 5}
7 const items = { first:1, second:1, ...others }
8 items //{ first: 1, second: 2, third: 3, fourth: 4,
fifth: 5 }
9
10
11 //展開字符串
12
13 const str = 'hello'
14 const array_str_ = [...str] //
- Array.from
1 //Array.from方法用於將兩類對象轉爲真正的數組
2 var args = Array.from(arguments);
3 var list = Array.from(document.querySelectAll('li'));
- Array.of()
1 //這個方法的主要目的,是彌補數組構造函數Array()的不足。
因爲參數個數的不同,會導致Array()的行爲有差異。
2 Array() // []
3 Array(3) // [, , ,]
4 Array(3, 11, 8) // [3, 11, 8]
5
6 Array.of(3, 11, 8) // [3,11,8]
7 Array.of(3) // [3]
8 Array.of(3).length // 1
## 8、for of 循環
1 看一下咱們會的循環方法
2 for 無法循環對象
3 for in 存在問題 他會遍歷所有可遍歷屬性
如果爲原型加了一些屬性,那也會遍歷出來
4 forEach 循環數組 無法終止
5
6 最終es6爲了統一,也借鑑了c++,java,python語言引入了for of
循環 作爲遍歷所有數據結構的統一的方法。
7 for...of循環可以使用的範圍包括數組、Set 和 Map 結構、
8 某些類似數組的對象
(比如arguments對象、DOM NodeList 對象)、
9 後文的 Generator 對象,以及字符串。
10 -- 對象不能使用for of
1 for(let v of [1,2,3]) {
2 console.log(v); // 1 2 3
3 }
4 let p = document.querySelectorAll("p");
5 for (let x of p) {
6 console.log(x);
7 }
## 9、set
1 //ES6 提供了新的數據結構 Set。它類似於數組,
但是成員的值都是唯一的,沒有重複的值。
2
3 const set = new Set([1, 2, 2, 4, 4]);
4 [...set]
5 //用Set 去重非常方便 ,數組去重面試常考題
6
7 [...new Set(arr)]
來源: https://www.cnblogs.com/ljyn/p/15879335.html
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/tRylEBaW1A_VL9V0aAKqag