ECMASctipt6總結
1.let 變量聲明以及特性
聲明變量
let a; let b, c, d; let e = 1; let f = 2, g = 3;
特性
1.不能重複聲明
2.塊級作用域 只在塊級作用域有效
3.沒有變量提升
4.不影響作用域鏈
2.const 常量聲明以及特性
特性
1.必須有初始值
2.一般常量使用大寫
3.常量的值不能修改
4.也是塊級作用域
5.對於數組和對象的修改,不算對常量的修改,不會報錯(可以對數組和對象進行修改,指向的地址沒有改變)
3.變量的解構賦值
1.數組的解構
const RNG = ['uzi', 'mlxg', 'letme', 'ming'] let [a, b, c, d] = RNG;// 每個值就是數組的位置對應的值
2.對象的解構
const UZI= { name: '自豪', age: 22, love: 'LOL', lol: function(){ alert('打lol') } } let {name, age, love} = UZI;// 每個值是對象中對應的值 let {lol} = UZI; lol();// 使用
4.模板字符串 “
1.內容中可以直接出現換行符,單引號雙引號內容不能直接用換行符(需要通過引號加號拼接)
let str = `lol s10 tes 是冠軍`;// 可以這樣直接使用換行符
2.直接進行變量的拼接 ${}
let lol = 'lol十周年';
let uzi = `${lol} 中國隊奪冠`
5.對象的簡寫
let name = 'zhangning187'; let change = function(){ console.log('努力改變'); } const supwisdom = { name, change }
6.箭頭函數及聲明特點 =>
let fn = (a, b) => { return a + b; } fn(1, 2);// 3
特點
1.this是靜態的,this始終是指向函數聲明時所在作用域下的this值,他沒有自己的this
2.不能作為構造實例化對象
3.不能使用arguments變量
4.箭頭函數的簡寫
let add = n => {
return n*2; }
省略小括號,當形參有且只有一個的時候可以省略
省略花括號,當代碼體只有一條語句的時候,return 必須省略,語句的執行結果就是函數的返回值
let add = n => n*2;
7.函數參數的默認值
1.形參初始值
function add(a, b, c = 10) {// 當不傳遞c的時候,c的默認值是10,盡量把具有默認值的參數放在後面 return a + b + c; } add (1, 2);// 13
2.與解構賦值結合
function con({name, age, love, height = '18'}) {// 還可以給默認值 console.log(age);// 24 console.log(height);// 沒有傳遞,使用默認值 18 } con({ name: 'zhangning187', age: 24, love: 'js' })
8.rest參數
用於獲取參數的實參,用於代替arguments
rest參數是一個數組和es5中的arguments不一樣,arguments裏面是一個對象
獲取實參的方式
function data(a, b, ...args) {// rest 參數必須放到參數的最後面 console.log(a);// 1 console.log(b);// 2 console.log(args);// [3, 4, 5, 6, 7] } data(1, 2, 3, 4, 5, 6, 7);
9.擴展運算符 …
可以將數組轉換為逗號分隔的參數序列,將一個數組分割,並將各個項作為分離的參數序列傳遞給函數
const RNG = ['UZI', 'MLXG', 'LETME', 'MING']; console.log(...RNG)// UZI MLXG LETME MING 解構之後的序列 console.log(RNG);// ['UZI', 'MLXG', 'LETME', 'MING'] 返回的是一個數組 const a = [1,2], b=[3,6]; const c = [...a, ...b];// [1, 2, 3, 6]
10.Symbol 新的原始數據類型,表示獨一無二的值
他是javaScript 語言的第七種數據類型,是一種類似於字符串的數據類型
特點
1.Symbol 的值是唯一的,用來解決命名衝突的問題
2.Symbol 值不能與其他數據進行運算,也不能自己運算 + – * /
3.Symbol 定義的對象屬性不能使用for in循環遍歷,但是可以使用 Reflect.ownKeys 來獲取對象的所有鍵名
創建Symbol let s = Symbol();// s不可見,在內部實現唯一性 let s2 = Symbol('zhangning187');// 這裏面的字符串只是一個標誌,Symbol返回的值都是唯一的 let s3 = Symbol('zhangning187'); console.log(s2 == s3);// false,確定唯一性
Symbol.for()方法創建,這是一個對象,這種方式可以得出唯一的Symbol值 let s6 = Symbol.for('zhangning187'); let s8 = Symbol.for('zhangning187'); console.log(s6 ==s8);// true 得到唯一的Symbol值
// USONB you are so niubility 你很牛逼
undefined string Symbol object null number boolean
對象添加Symbol類型的屬性
let zn = { up: function(){}, down: function(){}, name: 'zhangning187', age: 24 } // 向對象zn中添加 up down 方法 // zn.up = function(){}// 這個可以添加但是不確定zn中是否存在up方法,可能會覆蓋原來的up方法 // 這時候需要考慮通過Symbol添加唯一的方法 // 聲明一個對象 let methods = { up: Symbol(), down: Symbol() } zn[methods.up] = function(){ console.log('我可以爬樓'); } zn[methods.down] = function(){ console.log('我可以下樓'); } console.log(zn);// 已經添加唯一的方法 up down let UZI = { name: '自豪', // Symbol(): function(){},// 這裡不能這樣直接使用, Symbol()是一個表達式,是一個動態的 [Symbol('lol')]: function(){ console.log('我會打lol'); }, [Symbol('籃球')]: function(){// Symbol()中還可以添加描述字符串 console.log('我可以打籃球') } } console.log(UZI);
11.迭代器(Iterator)
迭代器是一種接口,為各種不同的數據結構提供統一的訪問機制,任何數據結構只要部署Iterator接口,就可以完成遍歷操作
1.ES6創造了一種新的遍曆命令for…of循環,Iterator接口提供for…of消費
2.原生具備iterator接口的數據
Array Arguments Set Map String TypedArray NodeList
3.工作原理
a 創建一個指針對象,指向當前數據結構的起始位置
b 第一次調用對象的next方法,指針自動指向數據結構的第一個成員
c 接下來不斷調用next方法,指針一直往後移動,直到指向最後一個成員
d 每調用next方法返回一個包含value和done屬性的對象
自定義遍曆數據的時候,要想到迭代器
12.生成器函數的聲明與調用
生成器函數是ES6提供的一種異步編程解決方案,與傳統函數完全不同,就是一個特殊的函數
// 聲明 function * gen(){// * 可以靠左,也可以靠右,還可以放在中間 // console.log('hello'); yield '2020lpl牛批';// yield 語句可以算作函數代碼的分隔符 let two = yield 『uzi 退役了』; console.log(two); yield '湖人總冠軍'; } // 執行 let iterator = gen(); // console.log(iterator);// 返回結果是一個迭代器對象 console.log(iterator.next());// 需要執行迭代器對象中的next()方法,才會執行生成器函數 console.log(iterator.next());// 每個next()只會執行裏面一個yield語句,這個會輸出 『uzi 退役了』 // 傳遞參數 參數將作為上一個yield語句的返回結果 console.log(iterator.next('AAA'));// 第三次調用傳遞的參數將作為第二個yield 的返回結果 打印為AAA // 使用for of循環遍歷輸出 for(let v of gen()){ console.log(v);// 依次輸出yield語句中的值 }
案例:1s輸出 111 2s輸出 222 3s輸出 333
function one(){ setTimeout(()=>{ console.log('111') iterator.next(); }, 1000) } function two(){ setTimeout(()=>{ console.log('111') iterator.next(); }, 1000) } function three(){ setTimeout(()=>{ console.log('111') }, 1000) } // 生成器函數 function * gen(){ yield one(); yield two(); yield three(); } // 調用生成器函數 let iterator = gen(); iterator.next();
13.Promise 基本使用
Promise 是一個構造函數,用來封裝異步操作並可以獲取其成功或失敗的結果
1 Promise 構造函數 Promise(excutor){}
2 Promise.prototype.then 有兩個參數,兩個參數都是函數,
Promise對象成功狀態執行then中第一個函數,失敗執行第二個函數
3 Promise.prototype.catch
// 實例化 const p = new Promise((resolve, reject) => { // 通過resolve,reject這兩個函數來改變Promise對象的狀態, // resolve會改變p的狀態為成功,reject會改變p的狀態為失敗,然後去執行then裏面的方法 // 執行異步操作,以定時器為例,定時器也是異步 setTimeout(()=>{ //let data = '異步執行成功'; // resolve(data);// 調用resolve函數, p會變成一個成功的狀態,會執行then中的第一個方法 let err = '執行失敗'; reject(err);// 調用reject函數,p會變成一個失敗的狀態,會執行then中的第二個方法 }, 1000) }) // 成功會調用 promise 對象 then 方法 p.then(value => {// 成功 // console.log(value);// 控制台打印:異步執行成功 }, reason => {// 失敗 console.error(reason) })
Promise.prototype.then 特性
// then方法的返回結果是Promise對象,對象狀態由回調函數的執行結果決定 const p = new Promise((resolve, reject) => { setTimeout(()=>{ resolve('成功'); reject('失敗'); }, 1000); }); // then 的返回結果是一個Promise對象,就是result也是一個Promise對象,它的狀態由函數的執行結果決定的 const result = p.then(value => { console.log(value); // 1.如果返回的結果是 非Promise 類型的屬性,狀態為成功,返回值return 中的值 // 如果不寫return,函數內部不寫return返回結果是undefined,也不是Promise對象,狀態也是成功 // return 123; // 2.是 promise 對象, 該對象返回的狀態就決定了then方法返回promise對象狀態 return new Promise((resolve, reject)=>{ // resolve('ok');// then方法返回promise對象狀態為成功 reject('no');// then方法返回promise對象狀態為失敗 }) // 3.拋出錯誤 then方法返回promise對象狀態為失敗,錯誤值為拋出錯誤的值 throw new Error('出錯了'); }, reason => { console.err(reason); }); console.log(result); // 綜上總結,then方法可以鏈式調用 可以改變回調域的現象 p.then(value=>{}, reason=>{}) .then(value()=>{}).then();
舉例:多個請求都返回之後,獲取其中的數據
const p = new Promise((resolve, reject)=>{ resolve('第一次返回成功') }); p.then(value=>{ return new Promise((resolve, reject)=>{ resolve([value, '第二次返回成功']) }); }).then(value=>{ return new Promise((resolve, reject)=>{ resolve([...value, '第三次返回成功']) }); }).then(value=>{ console.log(value);// 返回值為三次請求都返回成功以後的值 });
14.集合set
新的數據結構Set(集合),它類似於數組,成員的值都是唯一的,集合實現了iterator接口,所以可以使用擴展運算符和for of遍歷
集合的屬性和方法
1 size 返回集合的元素個數
2 add 添加一個新元素,返回當前集合
3 delete 刪除元素,返回boolean值
4 has 檢測集合中是否包含某個元素,返回boolean值
5 clear 清空
// 聲明 let s = new Set(); let s2 = new Set([1, 2, 3, 6, 7]); console.log(s2);// 5 s2.add(8);// 添加新元素 console.log(s2);// 輸出 {1, 2, 3, 6, 7, 8} s2.delete(8); console.log(s2);// 輸出 {1, 2, 3, 6, 7} console.log(s2.has(8));// false // s2.clear();// 清空 let arr = [1, 2, 3, 3, 3, 6, 6, 8]; let arr2 = [1, 3, 6, 7, 8]; // 數組去重 let result = [...new Set(arr)]; // 交集 let result = [...new Set(arr)].filter(item => new Set(arr2).has(item)); // 並集 let result = [...new Set([...arr, ...arr2])]; // 差集 arr有arr2中沒有 let result = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
15.Map集合
類似於對象,也是鍵值對的集合,但是 鍵 不限於字符串,各種類型的值(包括對象)都可以當作鍵,
map也實現了 iterator 接口,所以可以使用擴展運算符和for of進行遍歷
1 size 返回 Map 的元素個數
2 set 增加一個新元素,返回當前Map
3 get 返回鍵名對象的鍵值
4 has 檢測Map中是否包含某個元素,返回boolean值
5 clear 清空集合,返回undefined
// 聲明 let m = new Map(); m.set('name', 'zhangning'); m.set('change', function(){console.log('變得更努力')});// 鍵 change 值 一個function let key = {company: 'supwisdom'}; m.set(key, [1, 2, 3]);//鍵 對象 值 數組 m.size;// 獲取m個數 m.delete('name');// 刪除鍵值對 m.get('change');// 獲取鍵對應的值 // m.clear();// 清空 for(let v of m){console.log(v);}
16.class 類
通過class可以定義類,新的class寫法只是讓對象原型的寫法更加清晰,更像面向對象編程的語法而已。
1 class 聲明類
2 constructor 定義構造函數初始化
3 extends 繼承父類
4 super 調用父級構造方法
5 static 定義靜態方法和屬性
6 父類方法可以重寫
// es5通過 構造函數實例化 對象的方法
// 人 function People(name, sex) { this.name = name; this.sex = sex; } // 這個height這種添加方式是屬於函數對象的,不屬於實例對象,這樣的屬性稱之為靜態成員 People.height = '180'; People.prototype.height1 = '100'; // 添加方法 People.prototype.play = function(){ console.log('打籃球'); } let zn = new People('zhangning', '男'); zn.play();// 輸出 打籃球 console.log(zn); console.log(zn.height);// 輸出 undefined console.log(zn.height1);// 輸出 100,必須通過prototype添加才能添加到實例對象上
通過class實現
class People{ // 靜態屬性 static,對於static 標註的方法屬於類,不屬於實例對象 static height = '100'; static change(){ console.log('我可以改變世界'); } // 構造方法 名字不能更改(在使用new People的時候會自動執行實例對象上的constructor方法) constructor(name, sex){ this.name = name; this.sex = sex; } // 添加方法必須使用該語法,不能使用es5的完整形式(play: function(){} 這種形式不支持,必須使用play()形式) // 成員屬性 play(){ console.log('打籃球'); } } let zn = new People('zhangning', '男'); console.log(zn); console.log(zn.height);// undefined static 標註的方法屬於類,不屬於實例對象 console.log(People.height);// 100
使用es5構造函數實現繼承
// 舉例 chinese 繼承 People 屬性 function People(name, sex) { this.name = name; this.sex = sex; } People.prototype.play = function(){ console.log('打LOL'); } function Student(name, sex, like, height){ // 通過call方法,改變this值,this指向chinese中的this,也就是chinese的一個實例對象 People.call(this, name, sex); this.like = like; this.height = height; } // 設置子集構造函數原型 Student.prototype = new People;// 這樣就會有父級的一個方法 Student.prototype.constructor = Student;// 做一個校正,沒有這行代碼也無所謂 // 聲明子類方法 Student.prototype.photo = function(){ console.log('去拍照'); } // 實例化 const zn = new Student('zhangning', '男', '打籃球', '187'); console.log(zn)
使用es6 class 類 實現繼承 及 父類方法的重寫
// 聲明父類 class People{ // 父類構造方法 constructor(name, sex) { this.name = name; this.sex = sex; } // 父類成員屬性 play(){ console.log('打LOL'); } } // 聲明子類 使用extends 繼承父類 class Student extends People { // 構造方法 constructor(name, sex, like, height){ super(name, sex);// super 就是父類的constructor構造函數,這樣調用 this.like = like; this.height = height; } photo(){ console.log('去拍照'); } // 對父類中的play方法進行重寫,子類是不能去調用父類的同名方法的, play(){ // super(); 不允許,在普通的成員方法裏面是不能出現super()去調用父類的同名方法的,會報錯,只能完全重寫 console.log('我會打LOL,還會打籃球'); } } const zn = new Student('zhangning', '男', '打籃球', '187'); console.log(zn)
class 中 getter 和 setter 設置
class People{ get like(){ return '打籃球'; } set like(newVal){ // 通過傳過來的newVal值,進行操作,改變 like console.log('改變like值'); } } let p = new People(); console.log(p.like)// 輸出 打籃球 p.like = 'LOL';// 然後通過 set like 進行操作
17.對象數值擴展
1 Object.is 判斷兩個值是否完全相等
Object.is(1, 1);// true
和 === 很相似,唯一區別就是 NaN === NaN 為 false, Object.is(NaN, NaN) 為true
2 Object.assign 對象的合併
const c1 = {name: 'znn'}; const c2 = {name: 'zhangning', height: 187}; Object.assign(c1, c2);// 如果兩個對象中存在相同屬性,c2 中覆蓋c1中的屬性內容
3 Object.setPrototypeOf 設置原型對象
const zn = { name: 'zhangning', } const p = { h: true, sfsfdf: 'fasfasdf' } Object.setPrototypeOf(zn, p);// 設置 zn 的原型裏面有 p Object.getPrototypeOf(zn);// 獲取 zn 的原型 console.log(zn);// 打印看下