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 |
ES6兼容性查看:http://kangax.github.io/compat-table/es6/es6
使用Babel解決ES6兼容性問題github
提早編譯ajax
首先咱們建立一個html文件,在裏面輸入ES6的新語法,用低版本瀏覽器運行這個文件。編程
<script> let a = 1; console.log(a); </script>
這樣咱們的低版本瀏覽器會報錯:
json
此次咱們引入在線的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的結果:
1.能夠重複聲明,在團隊協做時很容易形成衝突
var a = 1; var a = 2;
2.沒法限制修改,沒有常量的概念
var a = 1; a = 2;
3.不支持塊級做用域,屬於函數級做用域
if ( true ) { var a = 1; } alert(a);
let a = 1; let a = 2; const a = 1; const a = 2;
2. 支持塊級做用域,在做用域內定義的變量或常量只能在做用域內使用
if ( true ) { let c = 1; } console.log(c);
if ( true ) { const PI = 3.14; } console.log(PI);
var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2]; console.log(a, b, c);
let [a, b, c] = [1, 2, 3]; console.log(a, b, c);
function fn(a){ return a * 2; } console.log(fn(5)); //10
let fn = (a) => { return a * 2; } console.log(fn(5)); //10
let fn = a => a * 2; console.log(fn(5)); //10
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
檢查分數是否及格
let arr = [59, 60, 99, 31, 85]; let result = arr.map(item => item >= 60 ? "及格" : "不及格"); console.log(result); //["不及格", "及格", "及格", "不及格", "及格"]
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
根據條件判斷,去掉不想要的數據,返回想保留的數據
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]
遍歷數組,第一個參數是數組的值,第二個參數是數組的下標
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
let str = "https://www.baidu.com/"; console.log(str.startsWith("https://")); //true
let str = "1.txt"; console.log(str.endsWith(".txt")); //true
var title = "標題"; var content = "內容"; var str = "<div>\ <h2>title:"+title+"</h2>\ <p>content:"+content+"</p>\ </div>";
let title = "標題"; let content = "內容"; let str = `<div> <h2>title:${title}</h2> <p>content:${content}</p> </div>`;
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
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
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
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.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.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
let a = 1; let b = 2; let json = {a: a, b: b, c: 3}; let json = {a, b, c: 3}; //簡寫
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();
————————————————