ECMAScript 6.0基礎入門教程

ECMAScript 6.0基礎入門教程

一、ES6簡介

1.1 ES6的歷史

  • ECMAScript簡稱ECMA或ES
  • ECMAScript與JavaScript的關係java

      ECMA是European Computer Manufacturers Association的縮寫,即歐洲計算機制造商協會。歐洲計算機制造商協會是制定信息傳輸與通信的國際化標準組織。
      1996年11月,JavaScript的創造者Netscape公司,決定將JavaScript提交給ECMA,但願這種語言可以成爲國際標準。次年,ECMA發佈262號標準文件(ECMA-262)的初版,規定了瀏覽器腳本語言的標準,並將這種語言稱爲ECMAScript,這個版本就是1.0版。
      該標準從一開始就是針對JavaScript語言制定的,但之因此不叫JavaScript,有兩個緣由。一是商標,Java是Sun公司的商標,根據受權協議,只有Netscape公司能夠合法地使用JavaScript這個名字,且JavaScript自己也已經被Netscape公司註冊爲商標。二是想體現這門語言的制定者是ECMA,不是Netscape,這樣有利於保證這門語言的開放性和中立性。
      所以,ECMAScript和JavaScript的關係是,ECMA是JavaScript的標準,JavaScript是ECMA的一種實現。jquery

  • 歷史版本git

    時間 版本 詳情
    1996.11 ES 1.0 Netscape將JS提交給ECMA組織,ES正式出現
    1998.06 ES 2.0 ES2正式發佈
    1999.12 ES 3.0 ES3被普遍支持
    2007.10 ES 4.0 ES4過於激進被廢棄
    2008.07 ES 3.1 4.0退化爲嚴重縮水版的3.1,由於吵的太厲害,因此ES 3.1代號爲Harmony(和諧)
    2009.12 ES 5.0 ES 5.0正式發佈,同時公佈了JavaScript.next也就是後來的ES 6.0
    2011.06 ES 5.1 ES 5.1成爲ISO國際標準
    2013.03 ES 6.0 ES 6.0草案定稿
    2013.12 ES 6.0 ES 6.0草案發布
    2015.06 ES 6.0 ES 6.0預計發佈正式版,JavaScript開始指向ES 7.0

1.2 ES6兼容性

  • ES6兼容性問題是怎樣產生的?
      因爲廣大用戶使用的瀏覽器版本在發佈的時候也許早於ES6的定稿和發佈,而到了今天,咱們在編程中若是使用了ES6的新特性,瀏覽器若沒有更新版本,或者新版本中沒有對ES6的特性進行兼容,那麼瀏覽器確定沒法識別咱們的ES6代碼,比如瀏覽器根本看不懂我寫的let和const是什麼東西?只能報錯了。這就是瀏覽器對ES6的兼容性問題。
  • 對ES6新特性最友好的瀏覽器有:IE10+、Chrome、FireFox、移動端、NodeJs
  • ES5兼容性查看:http://kangax.github.io/compat-table/es5/
  • ES6兼容性查看:http://kangax.github.io/compat-table/es6/es6

  • 使用Babel解決ES6兼容性問題github

    • 在線轉換:https://www.babeljs.cn/repl/
      babel
    • 提早編譯ajax

      • Babel是一個普遍使用的轉碼器,能夠將ES6代碼轉爲ES5代碼,從而使ES6在低版本瀏覽器環境運行。
      • 這種方法是實時在網頁中將ES6代碼轉爲ES5,對性能會有影響。生產環境須要將ES6轉碼完成再進行載入。
      • 首先咱們建立一個html文件,在裏面輸入ES6的新語法,用低版本瀏覽器運行這個文件。編程

        <script> let a = 1; console.log(a); </script>
      • 這樣咱們的低版本瀏覽器會報錯:
        let1json

      • 此次咱們引入在線的babel.min.js,咱們還要在script腳本中聲明類型爲」text/babel」,這樣就能夠在低版本瀏覽器中運行ES6的新語法了。

        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script> <script type="text/babel"> let a = 1; console.log(a); </script>
      • 此次咱們成功獲得了console.log的結果:
        let2

二、變量

2.1 var的缺點

1.能夠重複聲明,在團隊協做時很容易形成衝突

var a = 1; var a = 2;

2.沒法限制修改,沒有常量的概念

var a = 1; a = 2;

3.不支持塊級做用域,屬於函數級做用域

if ( true ) { var a = 1; } alert(a);

2.2 let和const

  • const是常量,常量命名要用大寫字母,值只能定義一次不可更改
  • let和const的區別是:let是變量能夠修改,const是常量不能夠修改
  • let和const的相同點:
    1.都不能重複聲明
let a = 1; let a = 2; const a = 1; const a = 2;

let
2. 支持塊級做用域,在做用域內定義的變量或常量只能在做用域內使用

if ( true ) { let c = 1; } console.log(c);

let做用域

if ( true ) { const PI = 3.14; } console.log(PI);

const做用域

2.3 解構賦值

  • 在ES5裏想要將數組內容分別賦值給變量必須單獨來寫
var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2]; console.log(a, b, c);
  • 經過ES6的解構賦值就能夠這樣來寫
let [a, b, c] = [1, 2, 3]; console.log(a, b, c);
  • 解構賦值注意事項
    1. 變量和數據必須一一對應
    2. 右側數據必須是合法的數據類型
    3. 聲明和賦值不能分開,必須在一句話裏完成

三、函數

3.1 箭頭函數

  • ES5的函數寫法
function fn(a){ return a * 2; } console.log(fn(5)); //10
  • ES6箭頭函數
let fn = (a) => { return a * 2; } console.log(fn(5)); //10
  • 箭頭函數簡寫,若是隻有一個參數能夠省略(),若是隻有一個return能夠省略{}和return
let fn = a => a * 2; console.log(fn(5)); //10

3.2 函數參數

  • 收集剩餘參數
    在參數最後添加形參…args獲取剩餘參數
let fn = (a, b, ...args) => { console.log(a); //1 console.log(b); //2 console.log(args); //[3, 4, 5] } fn(1, 2, 3, 4, 5);
  • 數組展開
let arr1 = [1, 2, 3]; let arr2 = [4, 5, 6]; let arr = [...arr1, ...arr2]; console.log(arr); //[1, 2, 3, 4, 5, 6]
  • 默認參數
    將形參直接賦值,若是沒有傳入對應實參那就使用默認值,若是傳入對應實參,那就使用實參
let fn = (a, b=2, c=3) => { console.log(a, b, c); //1, 5, 3 } fn(1, 5);

四、數組

ES6新增了4個數組方法:map、reduce、filter、forEach

4.1 map(映射)

檢查分數是否及格

let arr = [59, 60, 99, 31, 85]; let result = arr.map(item => item >= 60 ? "及格" : "不及格"); console.log(result); //["不及格", "及格", "及格", "不及格", "及格"]

4.2 reduce(彙總)

  • 求和
    tmp參數爲上一次相加的結果,item參數是當前要相加的值,index參數是當前要相加值的下標,arr參數指向的是數組自己
    reduce
let arr = [10, 20, 30, 40]; let result = arr.reduce((tmp, item, index) => tmp + item); console.log(result); //100
  • 求平均數
let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((tmp, item, index, arr) => { if ( index != arr.length-1 ) { //不是最後一次先求和 return tmp + item; } else { //最後一次求平均數 return (tmp + item)/arr.length; } }); console.log(result); //3

4.3 filter(過濾器)

根據條件判斷,去掉不想要的數據,返回想保留的數據

let arr = [5, 7, 10, 13, 15, 20, 25]; let result1 = arr.filter(item => { if ( item%5 == 0 ) { //判斷可不能夠被5整除 return true; //保留能夠被5整除的數 } else { return false; //去掉不能被5整除的數 } }); //能夠簡寫成下面這種方式,直接經過布爾值判斷,爲true的保留,爲false的去掉 let result2 = arr.filter(item => item%5 == 0); //保留能夠被5整除的數 //這樣獲得的結果是同樣的 console.log(result1); //[5, 10, 15, 20, 25] console.log(result2); //[5, 10, 15, 20, 25]

4.4 forEach(迭代)

遍歷數組,第一個參數是數組的值,第二個參數是數組的下標

let arr = [2, 5, 6, 9, 7, 54]; arr.forEach((item, index) => { console.log(index + ":" + item); //0:2, 1:5, 2:6, 3:9, 4:7, 5:54 });

五、字符串

ES6新增了2個字符串方法:startsWith、endsWith

5.1 startsWith(判斷字符串開始字符)

let str = "https://www.baidu.com/"; console.log(str.startsWith("https://")); //true

5.2 endsWith(判斷字符串結尾字符)

let str = "1.txt"; console.log(str.endsWith(".txt")); //true

5.3 字符串模板

  • 用反單引號將字符串和變量拼接,變量用${}包裹,字符串能夠換行。
  • ES5的字符串拼接很麻煩
var title = "標題"; var content = "內容"; var str = "<div>\ <h2>title:"+title+"</h2>\ <p>content:"+content+"</p>\ </div>";
  • 使用ES6字符串模板能夠更方便更簡潔
let title = "標題"; let content = "內容"; let str = `<div> <h2>title:${title}</h2> <p>content:${content}</p> </div>`;

六、面向對象

  • ES5的面向對象寫法很繁瑣,其實就是構造函數假裝成一個類來使用,代碼維護起來也比較麻煩。
function My(name, age){ //構造函數假裝成類來使用 this.name = name; this.age = age; } /*函數須要用prototype來追加,與主體分離,比較分散不便於維護*/ My.prototype.showName = function (){ alert(this.name); } My.prototype.showAge = function (){ alert(this.age); } var my = new My('Sain', 26); my.showName(); //Sain my.showAge(); //26
  • 在ES6裏增長了class關鍵字能夠區分類和構造函數,代碼都在同一個class做用域代碼方便管理
class My{ //使用class關鍵字定義一個類 constructor(name, age){ this.name = name; this.age = age; } showName(){ alert(this.name); } showAge(){ alert(this.age); } } var my = new My('Sain', 26); my.showName(); //Sain my.showAge(); //26
  • ES5的繼承方式
function addMyWeight(name, age, weight){ //若是想在剛纔My這個類的基礎上增長新的屬性就要使用繼承 My.call(this, name, age); //經過call來繼承父級 this.weight = weight; } addMyWeight.prototype = new My(); addMyWeight.prototype.constructor = addMyWeight; addMyWeight.prototype.showWeight = function (){ alert(this.weight); } var my = new addMyWeight('Sain', 26, '80kg'); my.showName(); //Sain my.showAge(); //26 my.showWeight(); //80kg
  • ES6的繼承方式
class addMyWeight extends My{ //使用ES6的extend來繼承My這個類 constructor(name, age, weight){ super(name, age); //等同於call繼承父級 this.weight = weight //增長新屬性 } showWeight(){ //增長新方法 alert(this.weight); } } var my = new addMyWeight('Sain', 26, '80kg'); my.showName(); //Sain my.showAge(); //26 my.showWeight(); //80kg

七、json

7.1 JSON對象

  • json數據串行化
    JSON.stringify()方法將json數據轉化成字符串
let json = {"a":10, "b": 5}; let str = JSON.stringify(json); console.log(str); //{"a":10, "b": 5} console.log(typeof str); //"string"
  • 字符串轉換成json
    JSON.parse()方法將字符串轉換成json,字符串必須嚴格遵照json格式要求,key和value要用雙引號包起來,value若是是數字的狀況下能夠不使用雙引號。
let str = '{"a": 10, "b": "hello"}'; let json = JSON.parse(str); console.log(json); //Object {a: 10, b: "hello"} console.log(typeof json); //object
  • 4

7.2 json簡寫

  • key和value的名字同樣的時候,能夠省略value
let a = 1; let b = 2; let json = {a: a, b: b, c: 3}; let json = {a, b, c: 3}; //簡寫
  • json內函數簡寫,能夠將函數的:function去掉,直接用函數名()的寫法
let json = { a: "hello", say: function(){ //能夠省略:和function,簡寫成say() alert(this.a); } } json.say(); //hello
 


八、Promise
Promise——承諾

8.1 異步
操做之間沒有關係
同時進行多個操做
回調寫法代碼複雜(回調地獄)
下面是異步操做代碼,若是想要同時讀取不一樣模塊的數據,就要寫成回調方式。

ajax('/top', function (top_data){
//top讀取成功
ajax('/left', function (left_data){
//left讀取成功
ajax('/right', function (right_data){
//right讀取成功
ajax('/bottom', function (bottom_data){
//bottom讀取成功
},function (){
console.log('bottom讀取失敗');
})
},function (){
console.log('right讀取失敗');
})
},function (){
console.log('left讀取失敗');
})
},function (){
console.log('top讀取失敗');
})

8.2 同步
同時只能作一件事
代碼排隊執行
代碼簡單,方便維護
下面是同步代碼,不一樣模塊分別調用,代碼簡潔:

let top_data = ajax_async('/top');
let left_data = ajax_async('/left');
let right_data = ajax_async('/right');
let bottom_data = ajax_async('/bottom');

8.3 Promise使用用法
Promise能夠消除異步操做,用同步的方式來書寫異步代碼
let p = new Promise(resolve,reject){
$.ajax({
url: 'a.txt',
dataType: 'json',
success(data){
resolve(data); //resolve成功
},
error(err){
reject(err); //reject失敗
}
})
}
p.then(function(data){
console.log('成功'+data);
}, function (err){
console.log('失敗'+err);
});

8.4 Promise.all()的使用方法
咱們用Promise建立了兩個異步操做,使用Promise.all()來同時執行這兩個操做,若是所有成功了就成功了,若是其中有一個失敗了就失敗了,等同於&&的關係。

除了Promise.all(),還有Promise.race() 方法,這兩個方法的使用方法同樣,不同的是Promise.race()只執行成功的,忽略失敗的,等同於||的關係。

let p1 = new Promise(resolve,reject){
$.ajax({
url: 'arr.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
let p2 = new Promise(resolve,reject){
$.ajax({
url: 'json.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
Promise.all([
p1, p2
]).then(
function (data){
let [res1,res2] = data; //解構賦值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一個失敗了就是失敗了');
}
)

8.5 封裝Promise
function createPromise(url){
return new Promise(resolve,reject){
$.ajax({
url, //key和value同樣,留一個就行
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
}
Promise.all([
createPromise('arr.txt');
createPromise('json.txt');
]).then(
function (data){
let [res1,res2] = data; //解構賦值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一個失敗了就是失敗了');
}
)

8.6 jquery的Promise使用
高版本jquery自帶Promise支持
先在頁面引入最新版本的jQuery<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

$.ajax({url: 'arr.txt, dataType: 'json'});

Promise.all([
$.ajax({url: 'arr.txt, dataType: 'json'});
$.ajax({url: 'json.txt, dataType: 'json'});
]).then(results => {
let [res1,res2] = results; //解構賦值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, err => {
console.log('有一個失敗了就是失敗了');
}
)

九、generator
generator生成器

普通函數:執行完才結束
generator函數:中間能暫停
9.1 generator函數的寫法
在function和函數名中加上*,能夠跟在function後面,也能夠在function和函數名中間,也能夠在函數名前面。

generator不能寫成箭頭函數方式。

function* show(){}
function * show(){}
function *show(){}

yield
```
function *show(){
console.log(1);
yield; //放棄執行
console.log(2);
}
let genObj = show(); //建立一個generator對象
genObj.next(); //1,調用next()執行一次

generator原理是生成了一堆小函數:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};

9.2 yield傳參、返回
yield傳參
function *show(){
let a = yield; //放棄執行
console.log(a); //5
}
let gen = show();
gen.next(10); //第一個next沒法傳參,第一個傳參要寫在generator函數參數裏
gen.next(5);

根據上面代碼咱們能夠知道generator沒法接收到第一個next方法的參數,咱們能夠將第一個參數直接傳入到generator函數參數裏:
function *show(num){
console.log(num); //10
let a = yield; //放棄執行
console.log(a); //5
}
let gen = show(10); //第一個next()傳參要寫在generator函數參數裏
gen.next();
gen.next(5);

generator原理是生成了一堆小函數:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};

yield返回
yield返回值有兩個參數:
1. value就是generator函數執行到當前yield語句以後獲得的值
2. done表示函數是否執行完成,true表明函數所有執行完成,flase表明函數暫停狀態未執行完成

function *show(){
console.log(1);
let a = yield; //放棄執行
console.log(2);
return 3;
}
let gen = show();
let res1 = gen.next();
console.log(res1); //{value:1,done:false}
let res2 = gen.next();
console.log(res2); //{value:undefined,done:true}
console.log(res2); //{value:3,done:true} 最後的返回值要經過return返回

9.3 generator的用途
當Promise有邏輯執行的時候會比異步回調寫法還麻煩,因此咱們在工做中遇到異步須要邏輯判斷的時候可使用generator來寫。
generator在有邏輯判斷狀況下寫起來很簡單
function *main(){
let data1 = yield $.ajax({url: '', dataType: 'json'});

if(data1.data == true) {
let data2 = yield $.ajax({url: '', dataType: 'json'});
} else {
let data3 = yield $.ajax({url: '', dataType: 'json'});
}
}
let gen = main();

————————————————

JavaScript 極簡史

相關文章
相關標籤/搜索