ES6看这一篇就够了
ES6新特性
什么是ES6?
ES6是ECMAScript6版本 簡稱 ES6 ,ES6在ES5的版本上新增了很多內容,簡化了代碼,提高了開發效率,真的很好用。
let
let是es6新增的作用在塊級作用域的聲明變量的方式
let 特點
? let 聲明變量 塊級作用域
1. 不能重復聲明3. 塊級作用域
4. 不影響作用域鏈
暫時性死區
ES6明確規定,如果區塊中存在 let 和 const 命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。
總之,在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱TDZ)。
“暫時性死區”也意味著 typeof 不再是一個百分之百安全的操作。
const
const 主要用于聲明常量
const特點
2. 一般都用大寫 (規范)
3. 常量的值不可修改
4. 塊級作用域
5. 對于數組 對象的元素修改 不算對常量的修改 不會報錯
解構賦值
解構賦值 : ES6 允許按照一定模式從數組和對象中提取值,對變量進行賦值 這被稱為解構賦值
交換變量
// 交換變量let a1 = 10;let b1 = 20;[b1,a1] = [a1,b1];console.log(b1);console.log(a1);數組解構賦值
// 數組解構賦值const F4 = ["A","B","C","D"];let [a,b,c,d] = F4;console.log(a +"-"+ b +"-"+ c +"-"+ d);let [q,w,e] = [1,2,3];console.log(q);console.log(w);console.log(e);let [head,...tail] = [1,2,3,4,5];console.log(head,tail);// 數組嵌套解構let [m1,m2,[m3,m4],m5] = [1,2,[3,4],6];console.log(m1,m2,m3,m4,m5);// 解構 不成功為 undefinedlet [q1,q2,q3] = [1];console.log(q1,q2,q3);對象解構賦值
// 對象數組進行解構let [name1,name2,name3] = [{name:1},{name:2},{name:3}];console.log(name1,name2,name3);// 對象的解構賦值let {name,age,play} = {name:"小牛",age:21,play:()=>console.log("play...")};console.log(name);console.log(age);console.log(play);// 可以不按照順序 數組和對象解構賦值的區別let {f2,f1} = {f1:"小妞妞",f2:"大妞妞"}console.log(f1,f2);// 對象解構并重命名const {f3:ff,f4} = {f3:10,f4:20};console.log(ff,f4);// 對象嵌套 解構賦值const {f5:{f6}} = {f5:{f6:"test-f6",f7:"test-f7"}};console.log(f6)// 解構對象并賦默認值let {f8 = "test8",f9="test9"} = {f8:"t8",f9:"t9"};console.log(f8,f9);字符串解構賦值
// 字符串 解構賦值const [r1,r2,r3] = "red";console.log(r1,r2,r3);// 類似數組 有一個length屬性 const {length:len} = "hello";console.log(len);數值與布爾值解構
// 數值與布爾值解構// 解構時,如果等號右邊的是數值或布爾值,則會先轉成對象let {toString:s} = 123;console.log(s === Number.prototype.toString); let {toString:ts} = true;console.log(ts === Boolean.prototype.toString); // 注意:Object里的toString()重寫了Function里的toString();/*解構賦值的規則是,只要等號右邊的值不是對象或數組,就先將其轉為對象,由于undefined和null無法轉為對象,所以它們進行解構賦值,都會報錯 */模板字符串
模板字符串 ES6 引入新的字符串方式 ``
// 1.聲明let str = `我也是一個字符串哦!`;console.log(str,typeof str);// 2. 可以出現換行符var strList = `<ul><li>迪迦</li><li>閃耀迪迦</li><li>黑暗迪迦</li></ul>`;console.log(strList);拼接js變量
// 3. 變量拼接 let girl = "小萌";let strGirl = `${girl}是我的傻憨憨`;console.log(strGirl);// 調用函數function fun(){return 'Hello Fun';}var strFun = `字符串可以調用${fun()}`;console.log(strFun)對象的簡化版
ES6 允許在{}中 直接寫入變量 函數 作為對象的屬性和方法
let name = "牛小牛";let chang = function(){console.log("我們可以改變你!");}const SCHOOL = {name,chang,/*show:function(){} 簡化了 之前的方法 聲明*/show(){console.log("簡化了函數的寫法");}}箭頭函數
箭頭函數聲明
// 箭頭函數聲明let fn = ()=>{// 代碼體}// 聲明并調用let fun = (a,b)=>{return a + b;}let result = fun(1,3);console.log(result);箭頭函數簡寫
// 箭頭函數的簡寫// 1. 當形參有且只有一個時 ()可以省略不寫 let getName = name => {console.log(name)};// 2. 當{} 方法體 只有一條語句時 {} 可以省略不寫 return 必須省略 let getUser = userName => console.log(userName);箭頭函數特性
函數默認值
ES6 允許函數的形參賦初始值
// 1. 形參初始值 具有默認值的 參數 寫在形參列表的最后(規范)function add(a,b,c=10){return a + b + c;}console.log(add(1,2));// 2. 結合解構賦值 使用function connetion({host,port,username,password}){console.log(host);console.log(port);console.log(username);console.log(password);}connetion({host:"localhst",port:3306,username:"root",password:"root"})Rest參數
ES6 引入 rest參數 用于獲取函數的實參,用來替代 arguments 對象 是一個可變長的參數
// ES5獲取實參的方式function date(){console.log(arguments);}date("白芷","大黃","防風")// ES6獲取實參的方式function date(...args){console.log(args);}date(1,2,3,4,5);擴展運算符
ES6 新增的 […] 擴展運算符 將數組轉換成以逗號分割的參數列表
const arr = ["小牛","雨花雨","花花牛"];// 聲明一個函數function getArr(){console.log(arguments);}getArr(...arr); // 合并數組const brr = ["閃耀迪迦","黑暗迪迦"];const crr = ["賽羅","貝利亞"];const drr = [...brr,...crr];console.log(drr);const err = [...brr,...crr,"奧特之王","雷歐"];console.log(err); // 數組克隆const old_arr = ["B","G","M"];const new_arr = [... old_arr];console.log(new_arr); // 將偽數組轉成真數組const dv = document.querySelectorAll("div");const dvs = [...dv];console.log(dvs);Symbol
什么是Symbol
Symbol
ES6 引入了 一種新的原始類型 Symbol 表示獨一無二的值,它是JavaScript 語言的第七種數據類型
是一種類似于字符串的數據類型。
Symbol特點
2. Symbol 值不能與其他的數據進行運算
3. Symbol 定義的對象不能使用for in 循環遍歷,但是可以使用Reflect.ownKeys來獲取對象的所有鍵名
創建Symbol
let s = Symbol();console.log(s ,typeof s);// Symbol(...) 中的 字符串 只做描述 主要為了在控制臺顯示,或者轉為字符串時便于區分let s2 = Symbol('牛小牛');let s3 = Symbol('牛小牛');// console.log(s2 === s3);// Symbol.for 創建 函數對象let s4 = Symbol.for("花花牛");let s5 = Symbol.for("花花牛");console.log(s4 === s5);不能和其他類型運算
let s6 = s2 + 100;let s7 = s2 < 100;let s8 = s2 >= 100;// 都是不能做的不能使用new 關鍵字
// Symbol 不能使用new 關鍵字 否則會報錯 ,因為它是原始類型 不是對象let s9 = new Symbol();Symbol類型轉換
// 可以轉換的console.log(String(Symbol("hello"))); // Symbol(hello)console.log(Symbol("hello").toString()); // Symbol(hello)console.log(!!Symbol("hello")); // true // 不可以轉換的console.log(Number(Symbol())); // Cannot convert a Symbol value to a number 不能轉為數字console.log(Symbol('hello') + 'world'); // Cannot convert a Symbol value to String 不能拼接字符串console.log(Symbol("hello") * 100); // 不能做任何運算添加Symbol類型的對象屬性
// 方式一// 直接在對象中添加屬性// Symbol 是動態的 添加屬性時 [Symbol]const play = {name : "play",[Symbol("say")]: function(){console.log("我可以說話")},[Symbol("zb")]: function(){console.log("你可以自爆");}}console.log(play);// 方式二let game = {name : "俄羅斯方塊",up(){},down(){}}// 聲明一個對象let methods = {up : Symbol(),down : Symbol()}game[methods.up] = function(){console.log("我可以向上");}game[methods.down] = function(){console.log("我可以向下");}console.log(game);不可以被for in 循環遍歷
// 不能被for in 循環遍歷 但是也不是私有屬性 可以通過 Object.getOwnPropertySymbol 方法獲取一個對象所有的Symbol屬性const datas = {[Symbol()] : 123,a:1,b:2}for(let i in datas){console.log(i);}console.log(Object.getOwnPropertySymbol(data)); // [Symbol()]console.log(data[Object.getOwnPropertySymbol(data)[0]]); // 123Symbol內置值
除了定義自己使用的Symbol值以外,ES6還提供了11個內置的Symbol值,指向語言內部使用的方法。
/* Symbol.hasInstanceSymbol.isConcatSpreadableSymbol.speciesSymbol.matchSymbol.replaceSymbol.searchSymbol.splitSymbol.iteratorSymbol.toPrimitiveSymbol.toStringTagSymbol.unscopables */迭代器
迭代器(Iterator)是一種接口,為各種不同的數據結構提供統一的訪問機制,
任何結構只要部署 Iterator 接口 就可以完成遍歷操作
? ES6 創造了一種新的遍歷命令 for … of 循環 ,Iterator 接口主要提供了 for … of消費
? 原生具備 Iterator 接口的數據(可用 for … of遍歷)
? Array Arguments Set Map String TypedArray NodeList 都繼承了Symbol(Symbol.iterator)
工作原理
工作原理:
創建一個指針對象,指向當前數據結構的起始位置
第一次調用對象的 next 方法,指針自動指向數據結構的第一個成員
接下來不斷調用 next 方法 指針一直往后移動 直到指向最后一個成員
每調用next方法返回一個包含value 和 done 屬性的對象 done 是否完成
自定義迭代器
自帶的Symbol.iterator 滿足不了我們的需求 需要自定義迭代器
const person = {name:"終極一擊",stus:["小牛","大牛","花花牛","牛小牛","奶味牛"], [Symbol.iterator](){// 索引變量let index = 0;let that = this;return{next:function(){// 如果 索引 小于 當前 數組的length done 就繼續執行if(index < that.stus.length){const result = {value:that.stus[index],done:false};index++;return result;}else{return {value:undefined,done:true}}}}}}for(let v of person){console.log(v);}生成器函數
生成器其實就是一個特殊的函數
// 異步編程 純回調函數
// 函數代碼的分隔符
格式: function * 函數名(){}
調用:
調用 需要用迭代器的.next()方法來調用
方法名.next() 調用
傳參
// 傳參// 方法名(形參)整體傳參function * gen(arg){console.log(arg);let one = yield "牛小牛";console.log(one);let two = yield "花花牛";console.log(two);let three = yield "雨花雨";console.log(three);}let iterator = gen("奶味牛");console.log(iterator.next());// next() 方法可以傳入實參 實參就是當前代碼段的返回值console.log(iterator.next("草莓牛"));console.log(iterator.next("藍莓牛"));console.log(iterator.next("菠蘿牛"));回調地獄
// 回調地獄 回調套回調setTimeout(()=>{console.log(111);setTimeout(()=>{console.log(222);setTimeout(()=>{console.log(333);},3000)},2000)},1000) // 生成器函數解決回調地獄function one(){setTimeout(()=>{console.log(111);iterator.next();},1000)}function two(){setTimeout(()=>{console.log(222);iterator.next();},2000)}function three(){setTimeout(()=>{console.log(333);iterator.next();},3000)}// 生成器函數function * gen(){yield one();yield two();yield three();}let iterator = gen();iterator.next(); function getUsers(){setTimeout(()=>{let data = "用戶數據";iterator.next(data);},1000);}function getOrders(){setTimeout(()=>{let data = "訂單數據";iterator.next(data);},1000);}function getGoods(){setTimeout(()=>{let data = "商品數據";iterator.next(data);},1000);}function * gen(){let users = yield getUsers();console.log(users);let orders = yield getOrders();console.log(orders);let goods = yield getGoods();console.log(goods);}let iterator = gen();iterator.next();Promise
Promise?
Promise 是 ES6引入的異步編程的新解決方案
語法上 Promise是一個構造函數 可以實例化對象
用來封裝異步操作并可以獲取其成功或失敗的結果。
1. Promise 構造函數 : Promise(excutor){}
2. Promise.prototype.then 方法
3. Promise.prototype.catch 方法
then
調用then 方法 then方法 的返回結果是Promise對象 對象狀態由回調函數的執行結果決定
如果 回調函數中返回結果是 非 Promise類型的屬性,狀態為成功,返回值為對象執行成功的值。
catch
catch 方法 主要用來控制 Promise() 錯誤的回調函數
const p = new Promise((resolve,reject)=>{setTimeout(reject("出錯了"),1000);})// catch 方法 主要用來控制 Promise() 錯誤的回調函數p.catch(reason=>console.log("又出錯了!!!"));Promise封裝Ajax
const p = new Promise(function(resolve,reject){// 創建對象const xhr = new XMLHttpRequest();// 初始化xhr.open("get","http://localhost:8080/heroall");// 發送xhr.send();// 綁定事件 處理響應結果xhr.onreadystatechange = function(){if(xhr.readyState == 4){if(xhr.status == 200){resolve(xhr.responseText);}else{reject(xhr.status);}}}});p.then(function(value){h2.innerHTML = value;},function(reason){h2.innerHTML = reason;})Promise讀取單個文件
// 引入 fs 模塊 const fs = require("fs"); // 讀取文件 fs.readFile("../lz.md",(err,data)=>{// 如果失敗 則拋出異常if(err) throw err;// 如果沒有出錯 則輸出內容console.log(data.toString()); }); // Promise讀取文件 const p = new Promise(function(resolve,reject){fs.readFile("../lz.md",(err,data)=>{// 如果失敗 調用reject()if(err) reject(err);// 如果成功 調用resolve()resolve(data);}); }); p.then(function(value){console.log(value.toString()); },function(err){console.log("讀取失敗"); })Promise讀取多個文件
// 引入 fs const fs = require("fs"); // 回調地獄 // fs.readFile("../lz.md",(err,data1)=>{ // fs.readFile("../jj.md",(err,data2)=>{ // fs.readFile("../yr.md",(err,data3)=>{ // let result = data1 + "\r\n" + data2 + "\r\n" + data3; // console.log(result); // }) // }) // }) // Promise 讀取多個文件 const p = new Promise(function(resolve,reject){fs.readFile("../jj.md",(err,data)=>{resolve(data);}) }); p.then(value=>{return new Promise((resolve,reject)=>{fs.readFile("../lz.md",(err,data)=>{resolve([value,data]);})}) }).then(value=>{return new Promise((resolve,reject)=>{fs.readFile("../yr.md",(err,data)=>{// 壓入 value.push(data);resolve(value);})}); }).then(value=>{console.log(value.toString()) });Set
ES6 提供了新的數據結構 Set(集合) 它類似與數組,但成員的值都是唯一的
集合實現了 iterator 接口 所以可以使用[…]擴展運算符 和 for of遍歷
集合屬性和方法
size 返回集合元素的個數add 添加一個新元素 返回當前集合delete 刪除元素 返回 boolean值has 檢測集合中是否包含某個元素 返回boolean值 const set = new Set();let s = new Set(["小牛","花花牛","奶味牛","牛小牛"]); // 集合元素個數console.log(s.size);// 添加元素console.log(s.add("奶味藍"));// delete 刪除元素console.log(s.delete("牛小牛"));// 檢測集合中是否包含某個元素console.log(s.has("小牛"))去重
let arr = [1,2,3,2,3,4,5,6,4,6];// 數組去重let uniq = [...new Set(arr)];console.log(uniq);并交叉
// 并集let union = [...new Set([...arr,...arr2])];console.log(union); --------------------------------// 交集// 方式一let arr = [1,2,3,2,3,4,5,6,4,6];let arr2 = [4,5,4,5,3,2,1];let result = [...new Set(arr)].filter(item=>{let s2 = new Set(arr2);if(s2.has(item)){return true;}else{return false;}}); --------------------------------// 方式二let arr = [1,2,3,2,3,4,5,6,4,6];let arr2 = [4,5,4,5,3,2,1];let rs = [...new Set(arr)].filter(item => new Set(arr2).has(item));console.log(rs); -----------------------------------------let arr = [1,2,3,2,3,4,5,6,4,6];let arr2 = [4,5,4,5,3,2,1];// 差集let diff = [...new Set(arr)].filter(item=> !new Set(arr2).has(item));console.log(diff);Map
ES6 提供了 Map 數據結構 它類似與對象 也是鍵值對的集合 但是 ‘鍵’ 的范圍不限于字符串
各種類型的值(包含對象) 都可以當做鍵 Map 也實現了 iterator 接口 所以可以使用 [擴展運算符]
和 [for of] 進行遍歷
Map屬性和方法
size 返回 Map的元素個數set 增加一個新元素 返回當前Mapget 返回鍵名對象的鍵值has 檢測Map中是否包含某個元素 返回booleanclear 清空 Map集合 返回undefined // 聲明 Maplet map = new Map();// 添加 鍵不可以重復 一旦重復 就是覆蓋map.set("M78","閃耀迪迦");map.set("!M78","黑暗迪迦");console.log(map);// 添加 值為函數map.set("fun",function(){console.log("我可以改變你!");});// 添加 鍵為對象const key = {name:"YUHUAYU"}map.set(key,["小牛","大牛"]);// 返回元素個數console.log(map.size);// 刪除元素console.log(map.delete("!M78"));// 獲取元素console.log(map.get("M78"));console.log(map.get(key));// 清空集合map.clear()// 遍歷集合for(let v of map){console.log(v);}class
class聲明
// class 聲明類class Phone{// 構造方法constructor(brand,price){this.brand = brand;this.price = price;}// 方法show(say){console.log(say)}}let phone = new Phone("onePlus",6999);console.log(phone.brand);phone.show("我可以打電話");靜態成員
// 靜態成員// 靜態成員只屬于 類 跟實例無關class Phone{static name = "小牛";static change(){console.log("我可以改變你");}}let phone = new Phone();console.log(Phone.name);Phone.change()類繼承
ES5
// ES5 繼承function Phone(brand,price){this.brand = brand;this.price = price;}Phone.prototype.call = function(){console.log("我可以打電話!");}function SmartPhone(brand,price,color,size){Phone.call(this,brand,price);this.color = color;this.size = size;}SmartPhone.prototype.playGame = function(){console.log("我可以玩游戲");}SmartPhone.prototype.photo = function(){console.log("我可以拍照");}let smartPhone = new SmartPhone("錘子",2999,"skyblue",5.5);console.log(smartPhone);ES6
class Phone{// 構造方法constructor(brand,price){this.brand = brand;this.price = price;}call(){console.log("我可以打電話");}}// 繼承 extends 關鍵字class SmartPhone extends Phone{constructor(brand,price,color,size){super(brand,price);this.color = color;this.size = size;}playGame(){console.log("我可以玩游戲")}photo(){console.log("我可以拍照")}}let smartPhone = new SmartPhone("錘子",9999,"gray",5.5);console.log(smartPhone);重寫父類的方法
// 只能完全重寫父類方法class Phone{constructor(brand){this.brand = brand;}call(){console.log("我可以打電話");}}class SmartPhone extends Phone{constructor(brand,color){super(brand);this.color = color;}playGame(){console.log("我可以玩游戲")}// 重寫父類的方法 如果不重寫父類的方法依然調用父類方法call(){console.log("我完全重寫了父類的方法了")}} let smartPhone = new SmartPhone("錘子","black");console.log(smartPhone);smartPhone.call();getter seter方法
getter
// getter setter 方法class Phone{// get方法 用來獲取值get price(){console.log("價格被讀取");return 2999;}}let phone = new Phone();// 調用get 方法console.log(phone.price);setter
class Phone{// set 方法設置值的時候 需要帶一個形參set price(newVal){console.log("價格被重置");}}let phone = new Phone();// 設置 setphone.price = 3999Number擴展
EPSILON
// Number.EPSILON 屬性的值接近于 2.22044604....function equal(a,b){if(Math.abs(a-b) < Number.EPSILON ){return true;}else{return false;}}console.log(0.1 + 0.2 === 0.3);console.log(equal(0.1 + 0.2,0.3));進制
let b = 0b1010; // 二進制let o = 0o777; // 八進制let d = 100; // 十進制let x = 0xff // 十六進制 // Number.isFinite檢測一個數值是否有限 返回booleanconsole.log(Number.isFinite(3));console.log(Number.isFinite(100/0));console.log(Number.isFinite(Infinity)); // Number.isNaN// Number.isNaN 檢測一個數字是否為 NaNconsole.log(Number.isNaN(123)); // Number.parseInt// Number.parseInt() 將字符串轉換成整數console.log(Number.parseInt("123love")); // Number.parseFloat// Number.parseFloat() 提取小數console.log(Number.parseFloat("12.321you")); // Number.isInteger// 判斷一個數是否為整數console.log(Number.isInteger(5));console.log(Number.isInteger(2.5)); // Number.trunc// Math.trunc 將數字的小數部分去掉console.log(Math.trunc(3.5)); // Math.sign// Math.sign 判斷一個數到底為正數 負數 還是零console.log(Math.sign(100));console.log(Math.sign(0));console.log(Math.sign(-100));Object擴展
Object.is
Obect.is 判斷兩個值是否完全相等 跟 === 類似 但是 判斷NaN時不同
console.log( Object.is(100,100));console.log( Object.is(NaN,NaN)); console.log( NaN === NaN);Object.assign
Object.assign 對象的合并
const config1 = {host:"127.0.0.1",port:3306,username:"root",password:"root",test:"test"}const config2 = {host:"localhost",port:3306,username:"root",password:"123456"}// 如果兩個對象參數相同 第二個參數對象覆蓋第一個參數對象,如果第二個參數對象沒有那么合并第一個參數對象的參數console.log(Object.assign(config1,config2))Object.setPrototypeOf
Object.setPrototypeOf 設置原型對象 Object.getPrototypeOf
const person = {name : "小牛"}const cities = {xiaoniu : ['北京','上海','廣州']}// 將person對象原型 設置為 cities對象Object.setPrototypeOf(person,cities);console.log(Object.getPrototypeOf(person));console.log(person)模塊化
模塊化是將一個大程序文件,拆分成許多小文件,然后將小文件組合起來。
模塊化優勢
? 防止命名沖突
? 代碼復用
? 高維護性
模塊化產品
ES6 之前的模塊化規范有
CommonJS => NodeJs Browserify
AMD => requireJS
CMD => seaJS
模塊化語法
模塊功能主要有兩大命令構成: export 和 import
export 用于規定模塊對外接口 (暴露)
import 用于規定輸入其他模塊提供的功能 (引入)
模塊化script標簽
script標簽引入方式一
注意:類型要設置為mudule
script標簽引入方式二
在script標簽中 src= app.js 一個入口js
type=module
import 引入在app.js這個入口js中
瀏覽器不兼容 需要打包 轉es5代碼
import
import 用于規定輸入其他模塊提供的功能 (引入)
引入模塊化文件
通用引入
// 1 通用引入 引入所有 as 別名 賦值給as 后的變量 from 引入那個文件import * as m1 from "./es6-m1.js";import * as m2 from "./es6-m2.js";import * as m3 from "./es6-m3.js";解構賦值引入
// 2 解構賦值引入import {name,teach} from "./es6-m1.js";// 當兩個文件變量重名 可以用 as 別名import {name as uname,person} from "./es6-m2.js";// 默認暴露 default 也需要一個別名 asimport {default as df} from "./es6-m3.js";簡便引入
// 3 簡便引入 注意 簡便引入只能針對默認暴露import m3 from "./es6-m3.js";export
單個暴露
// export 關鍵字 對外暴露 export let name = "雨花雨"; export function teach(){console.log("我可以改變你!"); }統一暴露
// 統一暴露 let name = "牛小牛"; const person = {height:178,width:85 } export {name,person}默認暴露
// 默認暴露 是一個對象形式 export default{name:"奶味藍",change:function(){console.log("一只小奶牛");}}總結
以上是生活随笔為你收集整理的ES6看这一篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: @Transactional注解和Myb
- 下一篇: 如何批量制作结业证书