ES6特性总结
目錄
- ES6特性總結
- 簡介
- 什么是ECMAScript
- web1.0時代:
- web2.0時代:
- ES6新特性
- 1. let聲明變量
- 2. const聲明常量(只讀變量)
- 3. 解構表達式
- 數組結構
- 對象結構
- 4. 字符串擴展
- 幾個新的API
- 字符串模板
- 5. 函數優化
- 函數參數默認值
- 不定參數
- 箭頭函數
- 實戰:箭頭函數結合解構表達式
- 6. 對象優化
- 新增的API
- 聲明對象簡寫
- 對象的函數屬性簡寫
- 對象拓展運算符
- 7. map和reduce
- map
- reduce
- 8. Promise
- Promise語法
- 處理異步結果
- Promise改造以前嵌套方式
- 優化處理
- 9. 模塊化
- export
- import
ES6特性總結
簡介
ECMAScript6.0(以下簡稱ES6,ECMAScript是一種由Ecma國際(前身為歐洲計算機制造商協會,英文名稱是EuropeanComputerManufacturersAssociation)通過ECMA-262標準化的腳本程序設計語言)是JavaScript語言的下一代標準,已經在2015年6月正式發布了,并且從ECMAScript6開始,開始采用年號來做版本。即ECMAScript2015,就是ECMAScript6。它的目標,是使得JavaScript語言可以用來編寫復雜的大型應用程序,成為企業級開發語言。
每年一個新版本。
什么是ECMAScript
來看下前端的發展歷程:
web1.0時代:
最初的網頁以HTML為主,是純靜態的網頁。網頁是只讀的,信息流只能從服務的到客戶端單向流通。開發人員也只關心頁面的樣式和內容即可。
web2.0時代:
- 1995年,網景工程師BrendanEich花了10天時間設計了JavaScript語言。
- 1996年,微軟發布了JScript,其實是JavaScript的逆向工程實現。
- 1996年11月,JavaScript的創造者Netscape公司,決定將JavaScript提交給標準化組織ECMA,希望這種語言能夠成為國際標準。
- 1997年,ECMA發布262號標準文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標準,并將這種語言稱為ECMAScript,這個版本就是1.0版。JavaScript和JScript都是ECMAScript的標準實現者,隨后各大瀏覽器廠商紛紛實現了ECMAScript標準。
所以,ECMAScript是瀏覽器腳本語言的規范,而各種我們熟知的js語言,如JavaScript則是規范的具體實現。
ES6新特性
1. let聲明變量
//var聲明的變量往往會越域//let聲明的變量有嚴格局部作用域{var a = 1;let b = 2;}console.log(a); //1console.log(b); //ReferenceError:bisnotdefined//var可以聲明多次//let只能聲明一次var m = 1var m = 2let n = 3//let n = 4console.log(m) //2console.log(n) //Identifier'n'hasalreadybeendeclared//var會變量提升//let不存在變量提升console.log(x); //undefinedvar x = 10;console.log(y); //ReferenceError:yisnotdefinedlet y = 20;2. const聲明常量(只讀變量)
//1.聲明之后不允許改變//2.一但聲明必須初始化,否則會報錯const a = 1;a = 3; //UncaughtTypeError:Assignmenttoconstantvariable.3. 解構表達式
數組結構
let arr = [1, 2, 3]; //以前我們想獲取其中的值,只能通過角標。ES6可以這樣: const [x, y, z] = arr; //x,y,z將與arr中的每個位置對應來取值//然后打印 console.log(x, y, z);對象結構
const person = {name: "jack",age: 21,language: ['java','js','css'] }//解構表達式獲取值,將person里面每一個屬性和左邊對應賦值 const {name, age, language} = person; //等價于下面 //const name = person.name; //const age = person.age; //const language = person.language; //可以分別打印 console.log(name); console.log(age); console.log(language);//擴展:如果想要將name的值賦值給其他變量,可以如下,nn是新的變量名 const {name: nn, age, language} = person; console.log(nn); console.log(age); console.log(language);4. 字符串擴展
幾個新的API
ES6為字符串擴展了幾個新的API:
- includes():返回布爾值,表示是否找到了參數字符串。
- startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。
- endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。
字符串模板
模板字符串相當于加強版的字符串,用反引號`,除了作為普通字符串,還可以用來定義多行字符串,還可以在字符串中加入變量和表達式。
//1、多行字符串 let ss = `<div><span>helloworld<span></div> `console.log(ss)//2、字符串插入變量和表達式。變量名寫在${}中,${}中可以放入JavaScript表達式。let name ="張三"; let age = 18; let info = `我是${name},今年${age}了`; console.log(info)//3、字符串中調用函數 function fun() {return"這是一個函數" }let sss = `O(∩_∩)O哈哈~,${fun()}`; console.log(sss); //O(∩_∩)O哈哈~,這是一個函數5. 函數優化
函數參數默認值
//在ES6以前,我們無法給一個函數參數設置默認值,只能采用變通寫法: function add(a, b) {//判斷b是否為空,為空就給默認值1b = b || 1;return a + b; }//傳一個參數 console.log(add(10));//現在可以這么寫:直接給參數寫上默認值,沒傳就會自動使用默認值 function add2(a, b = 1) {return a + b; } //傳一個參數 console.log(add2(10));不定參數
不定參數用來表示不確定參數個數,形如,…變量名,由...加上一個具名參數標識符組成。具名參數只能放在參數列表的最后,并且有且只有一個不定參數
function fun(...values){console.log(values.length) } fun(1, 2) //2 fun(1, 2, 3, 4) //4箭頭函數
ES6中定義函數的簡寫方式
- 一個參數時:
- 多個參數:
實戰:箭頭函數結合解構表達式
//需求,聲明一個對象,hello方法需要對象的個別屬性 //以前的方式: const person = {name: "jack",age: 21,language: ['java', 'js', 'css'] }function hello(person) {console.log("hello, " + person.name) } //現在的方式 var hello2 = ({name}) => {console.log("hello," + name)}; //測試 hello2(person);6. 對象優化
新增的API
ES6給Object拓展了許多新的方法,如:
- keys(obj):獲取對象的所有key形成的數組
- values(obj):獲取對象的所有value形成的數組
- entries(obj):獲取對象的所有key和value形成的二維數組。格式:[[k1, v1],[k2, v2],...]
- assign(dest,…src):將多個src對象的值拷貝到dest中。(第一層為深拷貝,第二層為淺拷貝)
聲明對象簡寫
const age = 23 const name = "張三" //傳統 const person1 = {age: age, name: name} console.log(person1)//ES6:屬性名和屬性值變量名一樣,可以省略 const person2 = {age, name} console.log(person2) //{age:23,name:"張三"}對象的函數屬性簡寫
let person = {name: "jack",//以前:eat: function(food) {console.log(this.name+"在吃"+food);},//箭頭函數版:這里拿不到thiseat2: food => console.log(person.name + "在吃" + food);//簡寫版:eat3(food) {console.log(this.name + "在吃" + food);} } person.eat("apple");對象拓展運算符
拓展運算符(…)用于取出參數對象所有可遍歷屬性然后拷貝到當前對象。
//1、拷貝對象(深拷貝) let person1 = {name: "Amy", age: 15} let someone = {...person1} console.log(someone)//{name: "Amy", age: 15} //2、合并對象 let age = {age: 15} let name = {name: "Amy"} let person2 = {...age, ...name} //如果兩個對象的字段名重復,后面對象字段值會覆蓋前面對象的字段值 console.log(person2) //{age: 15, name: "Amy"}7. map和reduce
數組中新增了map和reduce方法。
map
map():接收一個函數,將原數組中的所有元素用這個函數處理后放入新數組返回。
let arr = ['1', '20', '-5', '3']; console.log(arr)arr = arr.map(s => parseInt(s)); console.log(arr)reduce
語法:
arr.reduce(callback,[initialValue])
reduce為數組中的每一個元素依次執行回調函數,不包括數組中被刪除或從未被賦值的元素,接受四個參數:初始值(或者上一次回調函數的返回值),當前元素值,當前索引,調用reduce的數組。
callback(執行數組中每個值的函數,包含四個參數)
- previousValue(上一次調用回調返回的值,或者是提供的初始值(initialValue))
- currentValue(數組中當前被處理的元素)
- index(當前元素在數組中的索引)
- array(調用reduce的數組)
initialValue(作為第一次調用callback的第一個參數。)
示例:
8. Promise
在JavaScript的世界中,所有代碼都是單線程執行的。由于這個“缺陷”,導致JavaScript的所有網絡操作,瀏覽器事件,都必須是異步執行。異步執行可以用回調函數實現。一旦有一連串的ajax請求a,b,c,d…后面的請求依賴前面的請求結果,就需要層層嵌套。這種縮進和層層嵌套的方式,非常容易造成上下文代碼混亂,我們不得不非常小心翼翼處理內層函數與外層函數的數據,一旦內層函數使用了上層函數的變量,這種混亂程度就會加劇…總之,這
種層疊上下文的層層嵌套方式,著實增加了神經的緊張程度。
案例:用戶登錄,并展示該用戶的各科成績。在頁面發送兩次請求:
分析:此時后臺應該提供三個接口,一個提供用戶查詢接口,一個提供科目的接口,一個提供各科成績的接口,為了渲染方便,最好響應json數據。在這里就不編寫后臺接口了,而是提供三個json文件,直接提供json數據,模擬后臺接口:
user.json: {"id": 1,"name": "zhangsan","password": "123456" } user_corse_1.json: {"id": 10,"name": "chinese" } corse_score_10.json: {"id": 100,"score": 90 } //回調函數嵌套的噩夢:層層嵌套。 $.ajax({url: "mock/user.json",success(data) {console.log("查詢用戶:", data);$.ajax({url:`mock/user_corse_${data.id}.json`,success(data){console.log("查詢到課程:", data);$.ajax({url:`mock/corse_score_${data.id}.json`,success(data) {console.log("查詢到分數:", data);},error(error) {console.log("出現異常了:" + error);}});},error(error){console.log("出現異常了:" + error);}});},error(error){console.log("出現異常了:" + error);} });我們可以通過Promise解決以上問題。
Promise語法
const promise = new Promise(function(resolve, reject) {//執行異步操作if(/*異步操作成功*/) {resolve(value); //調用resolve,代表Promise將返回成功的結果} else {reject(error);//調用reject,代表Promise會返回失敗結果} });//使用箭頭函數可以簡寫為: const promise = new Promise((resolve, reject) => {//執行異步操作if(/*異步操作成功*/) {resolve(value);//調用resolve,代表Promise將返回成功的結果} else {reject(error);//調用reject,代表Promise會返回失敗結果} });這樣,在promise中就封裝了一段異步執行的結果。
處理異步結果
如果我們想要等待異步執行完成,做一些事情,我們可以通過promise的then方法來實現。如果想要處理promise異步執行失敗的事件,還可以跟上catch:
promise.then(function(value){//異步執行成功后的回調 }).catch(function(error){//異步執行失敗后的回調 })Promise改造以前嵌套方式
new Promise((resolve, reject) => {$.ajax({url:"mock/user.json",success(data){console.log("查詢用戶:", data);resolve(data.id);},error(error) {console.log("出現異常了:" + error);}}); }).then((userId) => {return new Promise((resolve, reject) => {$.ajax({url:`mock/user_corse_${userId}.json`,success(data) {console.log("查詢到課程:",data);resolve(data.id);},error(error) {console.log("出現異常了:"+error);}});}); }).then((corseId) => {console.log(corseId);$.ajax({url: `mock/corse_score_${corseId}.json`,success(data) {console.log("查詢到分數:", data);},error(error) {console.log("出現異常了:"+error);}}); });優化處理
優化:通常在企業開發中,會把promise封裝成通用方法,如下:封裝了一個通用的get請求方法;
let get = function(url, data) { //實際開發中會單獨放到common.js中return new Promise((resolve, reject) => {$.ajax({url:url,type:"GET",data:data,success(result) {resolve(result);},error(error) {reject(error);}});}) }//使用封裝的get方法,實現查詢分數 get("mock/user.json").then((result) => {console.log("查詢用戶:", result);return get(mock/user_corse_${result.id}.json); }).then((result) => {console.log("查詢到課程:",result);return get(mock/corse_score_${result.id}.json) }).catch(() => {console.log("出現異常了:" + error); });通過比較,我們知道了Promise的扁平化設計理念,也領略了這種上層設計帶來的好處。
我們的項目中會使用到這種異步處理的方式;
9. 模塊化
模塊化就是把代碼進行拆分,方便重復利用。類似java中的導包:要使用一個包,必須先導包。而JS中沒有包的概念,換來的是模塊。
模塊功能主要由兩個命令構成:export和import。
- export命令用于規定模塊的對外接口。
- import命令用于導入其他模塊提供的功能。
export
比如我定義一個js文件:hello.js,里面有一個對象
const util = {sum(a, b) {return a + b;} }我可以使用export將這個對象導出:
const util = {sum(a, b) {return a + b;} }export {util};當然,也可以簡寫為:
export const util = {sum(a, b) {return a + b;} }export不僅可以導出對象,一切JS變量都可以導出。比如:基本類型變量、函數、數組、對象。
當要導出多個值時,還可以簡寫。比如我有一個文件:user.js:
省略名稱
上面的導出代碼中,都明確指定了導出的變量名,這樣其它人在導入使用時就必須準確寫出變量名,否則就會出錯。
因此js提供了default關鍵字,可以對導出的變量名進行省略
例如:
這樣,當使用者導入時,可以任意起名字
import
使用export命令定義了模塊的對外接口以后,其他JS文件就可以通過import命令加載這個模塊。
例如我要使用上面導出的util:
//導入util import util from 'hello.js' //調用util中的屬性 util.sum(1, 2)要批量導入前面導出的name和age:
import {name, age} from 'user.js' console.log(name + ", 今年" + age + "歲了")但是上面的代碼暫時無法測試,因為瀏覽器目前還不支持ES6的導入和導出功能。除非借助于工具,把ES6的語法進行編譯降級到ES5,比如Babel-cli工具
文章已上傳gitee https://gitee.com/codingce/hexo-blog
項目地址github: https://github.com/xzMhehe/codingce-java
總結
- 上一篇: Linux系统简单介绍和基本命令
- 下一篇: hexo部署云服务器的全过程