ES6怎么來的
- ECMAScript 和 JavaScript
- ECMA 是標(biāo)準(zhǔn),JS 是實(shí)現(xiàn)
- ECMAScript 簡稱 ECMA 或 ES
- 歷史版本
- 1996, ES1.0 Netscape 將 JS 提交給 ECMA 組織,ES 正式出現(xiàn)
- 1999, ES3.0 被廣泛支持
- 2011, ES5.1 成為 ISO 國際標(biāo)準(zhǔn)
- 2015, ES6.0 正式發(fā)布
ES6兼容性
ES6(ES2015) 支持的環(huán)境 IE10+, Chrome, FireFox, 移動(dòng)端, NodeJS
-
解決不兼容辦法,編譯、轉(zhuǎn)換
- 在線轉(zhuǎn)換
- 提前編譯(推薦)
-
- Babel 入門教程 阮一峰
- Babel 是一個(gè) JavaScript 編譯器,與browser.js是同一詞
- 一個(gè)廣泛使用的轉(zhuǎn)碼器,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而在現(xiàn)有環(huán)境執(zhí)行
- 現(xiàn)在就用 ES6 編寫程序,而不用擔(dān)心現(xiàn)有環(huán)境是否支持
變量 let 和 常量 const
-
var 的問題
- 可以重復(fù)聲明,沒有報(bào)錯(cuò)和警告
- 無法限制修改
- 沒有塊級(jí)作用域,
{ }
-
let 和 const
- 不能重復(fù)聲明
- let 是變量,可以修改
- const 是常量,不能修改
- 都是塊級(jí)作用域, { } 塊內(nèi)聲明的,塊外無效
//重復(fù)聲明
var a = 12;
var a = 5;
alert(a);//執(zhí)行彈出5,瀏覽器不報(bào)錯(cuò)不警告
let a = 12;
let a = 5;
alert(a);//報(bào)錯(cuò)!
//變量和常量
let a = 12;
a = 5;
alert(a);//5
const a = 12;
a = 5;
alert(a);//報(bào)錯(cuò)!
//塊級(jí)作用域
{
let a = 1;
alert(a);//彈出1
}
alert (a);//報(bào)錯(cuò)!a is not defined
- 塊級(jí)作用域舉例
- 原來用 var 的方式,結(jié)果彈出的都是 3
- 或者將變量 封裝到函數(shù)里,限制作用域,但比較麻煩
- 用 let 最簡單,直接 var 改 let,解決作用域問題
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload= function () {
/*
var aBtn = document.getElementsByTagName('input')
for (var i=0; i < aBtn.length; i++) {
aBtn[i].onclick = function () {
alert(i)//3
}
}*/
/*
var aBtn = document.getElementsByTagName('input')
for (var i = 0; i < aBtn.length; i++) {
// 封裝到函數(shù)里,限制作用域
(function (i) {
aBtn[i].onclick = function () {
alert(i)
}
})(i)
}*/
var aBtn = document.getElementsByTagName('input')
for (let i = 0; i < aBtn.length; i++) {
aBtn[i].onclick = function () {
alert(i)
}
}
}
</script>
</head>
<body>
<input type="button" value="按鈕1">
<input type="button" value="按鈕2">
<input type="button" value="按鈕3">
</body>
</html>
函數(shù)-箭頭函數(shù)
- 箭頭函數(shù),就是函數(shù)的簡寫
- 如果只有一個(gè)參數(shù),
()可以省 - 如果只有一個(gè)
return,{}可以省
- 如果只有一個(gè)參數(shù),
- 修正this指向
// 普通函數(shù)
function name() {
}
// 箭頭函數(shù),去掉 function, 加上 =>
() => {
}
let arr = [12,5,8,99,34,13];
arr.sort(function (n1,n2){
return n1-n2;
});
arr.sort((n1,n2) => {
return n1-n2;
})
//如果只有一個(gè)參數(shù),`()` 可以省
//如果只有一個(gè)`return`,`{}`可以省
let show = a => a*2;//簡潔,類似python lambda 函數(shù)
let show = function (a){
return a*2;
}
函數(shù)-參數(shù)
- 參數(shù)擴(kuò)展/展開
...args- 收集剩余的參數(shù),必須是最后一個(gè)參數(shù)位置
- 展開數(shù)組,展開后效果和直接把數(shù)組的內(nèi)容寫在這兒一樣
- 默認(rèn)參數(shù)
//收集參數(shù)
function show(a,b,...args){
console.log(a);//12
console.log(b);//3
console.log(...args);//[45,55,78,23]
}
show(12,3,45,55,78,23);
//展開數(shù)組
let arr = [1,2,3];
//...arr
//1,2,3
function show(a,b,c){
alert(a);
alert(b);
alert(c);
}
//show(1,2,3);//正常調(diào)用數(shù)組
//show(...arr);//es6展開數(shù)組,效果相同
let arr1 = [1,2,3];
let arr2 = [5,6,7];
let arr = [...arr1,...arr2];
console.log(arr);//[1,2,3,5,6,7]
function show(...args){
fn(...args);
}
function fn(a,b){
alert(a+b);
}
show(12,5);
//默認(rèn)參數(shù)
function show(a,b=5,c=12){
console.log(a,b,c);
}
show(88);//88,5,12
show(88, 12);//88,12,12
show(88,12,4);//88,12,4
解構(gòu)賦值
- 左右兩個(gè)邊結(jié)構(gòu)必須一樣
- 右邊必須是個(gè)東西
- 聲明和賦值賦值不能分開,必須在一句話里完成
let [a, b, c] = [1, 2, 3]
console.log(a, b, c);//1,2,3
let {x, y, z} = {x: 1, y: 2, z: 3}
console.log(x, y, z);//1,2,3
let [json, arr, num, str] = [{ a: 1, b: 2 }, [1, 2, 3], 8, 'str']
console.log(json, arr, num, str);
//右邊必須是個(gè)東西
let [a,b] = {2,3};//報(bào)錯(cuò)!
//聲明和賦值賦值不能分開
let [a,b];
[a,b] = [1,2];//報(bào)錯(cuò)!
數(shù)組
- 新增4個(gè)方法,
map,reduce,filter,forEach -
map: 映射,一個(gè)對(duì)一個(gè)
let arr = [12, 5, 8];
let result = arr.map(function (item) {
return item*2
})
// 簡寫
let result2 = arr.map(item=>item*2);
console.log(result);//[ 24, 10, 16 ]
console.log(result2);//[ 24, 10, 16 ]
let score = [18, 86, 88, 24];
let result3 = score.map(item => item >= 60 ? '及格' : '不及格')
console.log(result3);//[ '不及格', '及格', '及格', '不及格' ]
-
reduce: 匯總,一堆出來一個(gè)- 用于比如,算個(gè)總數(shù),算個(gè)平均
//總和
var arr = [1, 3, 5, 7]
var result = arr.reduce(function (tmp, item, index) {
//tmp 上次結(jié)果,item當(dāng)前數(shù),index次數(shù)1開始
console.log(tmp, item, index);
return tmp + item;
})
console.log(result)
//求平均數(shù)
var arr = [1, 3, 5, 7]
var result = arr.reduce(function (tmp, item, index) {
if (index != arr.length - 1) {
// 不是最后一次
return tmp + item
} else {
//最后一次
return (tmp + item)/arr.length
}
})
console.log(result);
-
filter: 過濾器 ,保留為true的
//返回被3整除的數(shù)
var arr = [12, 4, 8, 9]
var result = arr.filter(item => (item % 3 === 0) ? true : false)
//簡化
var result = arr.filter(item => item % 3 === 0)
//價(jià)格篩選
var arr = [
{ title: '蘋果', price: 10 },
{ title: '西瓜', price: 20 },
]
var result = arr.filter(item=> item.price >= 20)
-
forEach: 循環(huán)迭代
var arr = [12, 4, 8, 9]
var result = arr.forEach(item => console.log(item))
var result = arr.forEach((item, index)=>console.log(item, index))
字符串
- 新增兩個(gè)方法
-
startsWith:以什么開頭 -
endsWith: 以什么結(jié)尾
-
var url = 'http://qq.com'
console.log(url.startsWith('http'));//true
console.log(url.endsWith('com'));//true
- 字符串模版
- 使用反引號(hào),
${變量}直接把東西塞到字符串中 - 可以折行
- 使用反引號(hào),
let a = 12
let str1 = `asdf${a}`
console.log(str1)
let title = '標(biāo)題'
let content = '內(nèi)容'
let str = `<div>
<h1>${title}</h1>
<p>${content}</p>
`
console.log(str)
<div>
<h1>標(biāo)題</h1>
<p>內(nèi)容</p>
面向?qū)ο?基礎(chǔ)
- 原來寫法
- 類和構(gòu)造函數(shù)一樣
- 屬性和方法分開寫的
//老版寫法
function User(name,pass){
this.name = name;
this.pass = pass;
}
User.prototype.showName = function(){
alert(this.name);
}
User.prototype.showPass = function(){
alert(this.pass);
}
var u1 = new User('bule','121212');
u1.showName();
u1.showPass();
//老版繼承
function VipUser(name, pass, level) {
User.call(this, name, pass)
this.level = level
}
VipUser.prototype = new User()
VipUser.prototype.constructor = VipUser
VipUser.prototype.showLevel = function () {
console.log(this.level)
}
var v1 = new VipUser('blue', '1234', 3)
v1.showName()
v1.showLevel()
- 新版面向?qū)ο?
- 有了 class 關(guān)鍵字、構(gòu)造器和類分開了
- class 里面直接加方法
- 繼承,super 超類==父類
class User {
constructor(name,pass){
this.name = name;
this.pass = pass;
}
showName(){
console.log(this.name);
}
showPass(){
console.log(this.pass);
}
}
//新版繼承
class VipUser extends User{
constructor(name,pass,level){
super(name,pass);
this.level = level;
}
showLevel(){
alert(this.level);
}
}
var v1 = new VipUser('blue', '1234', 3)
v1.showName()
v1.showLevel()
面向?qū)ο髴?yīng)用
-
React
- 用于構(gòu)建用戶界面的 JavaScript 庫
- 組件化,一個(gè)組件就是一個(gè) class
- 強(qiáng)依賴于JSX == bable == browser.js
json
- JSON 格式
- JavaScript Object Notation 的縮寫,是一種用于數(shù)據(jù)交換的文本格式
- JSON 是 JS對(duì)象 的嚴(yán)格子集
- JSON 的標(biāo)準(zhǔn)寫法
- 只能用雙引號(hào)
- 所有的key都必須用雙引號(hào)包起來
- JSON 對(duì)象
- JSON 對(duì)象是 JavaScript 的原生對(duì)象,用來處理 JSON 格式數(shù)據(jù),有兩個(gè)靜態(tài)方法
- JSON.parse(string) :接受一個(gè) JSON 字符串并將其轉(zhuǎn)換成一個(gè) JavaScript 對(duì)象。
- JSON.stringify(obj) :接受一個(gè) JavaScript 對(duì)象并將其轉(zhuǎn)換為一個(gè) JSON 字符串。
//json的標(biāo)準(zhǔn)寫法
let a = '{"a" : 12,"b" : "lalala"}';
let json = {"a":12,"b":5};
let str = 'hi,' + JSON.Stringify(json);//hi,{"a":12,"b":5}
var url = 'http://www.xx.com/' + encodeURIComponent(JSON.stringify(json));//http://www.xx.com/%7B%22a%22%3A12%2C%22b%22%3A5%7D
var str = '{"a": 12, "b": 4, "c": "abc"}'
var json = JSON.parse(str)
console.log(json);//{ a: 12, b: 4, c: 'abc' }
- json的簡寫
- 名字和值一樣時(shí),保留一個(gè)就可以
- json中包含的函數(shù)可以省略
:function
//老版
let json = {a:a,b:b};
//新版
let json = {a,b,c:123};
//老版
let json = {
a:12,
show:function(){
alert(this.a);
}
}
//新版
let json = {
a:12,
show(){
alert(this.a);
}
}
- 對(duì)象(object)
- 是 JavaScript 語言的核心概念,也是最重要的數(shù)據(jù)類型
對(duì)象就是一組“鍵值對(duì)”(key-value)的集合,是一種無序的復(fù)合數(shù)據(jù)集合 - 對(duì)象的所有鍵名都是字符串, 所以加不加引號(hào)都可以
如果鍵名是數(shù)值,會(huì)被自動(dòng)轉(zhuǎn)為字符串 - 對(duì)象的每一個(gè)鍵名又稱為“屬性”(property),它的“鍵值”可以是任何數(shù)據(jù)類型
- 如果一個(gè)屬性的值為函數(shù),通常把這個(gè)屬性稱為“方法”,它可以像函數(shù)那樣調(diào)用
- in 運(yùn)算符用于檢查對(duì)象是否包含某個(gè)屬性(注意,檢查的是鍵名,不是鍵值
- for...in循環(huán)用來遍歷一個(gè)對(duì)象的全部屬性
- 是 JavaScript 語言的核心概念,也是最重要的數(shù)據(jù)類型
Promise
-
異步和同步
- 異步,操作之間沒啥關(guān)系,可同時(shí)執(zhí)行多個(gè)操作, 代碼復(fù)雜
- 同步,同時(shí)只能做一件事,代碼簡單
-
Promise 對(duì)象
- 用同步的方式來書寫異步代碼
Promise 讓異步操作寫起來,像在寫同步操作的流程,不必一層層地嵌套回調(diào)函數(shù) - 改善了可讀性,對(duì)于多層嵌套的回調(diào)函數(shù)很方便
- 充當(dāng)異步操作與回調(diào)函數(shù)之間的中介,使得異步操作具備同步操作的接口
- 用同步的方式來書寫異步代碼
-
Promise 也是一個(gè)構(gòu)造函數(shù)
- 接受一個(gè)回調(diào)函數(shù)f1作為參數(shù),f1里面是異步操作的代碼
- 返回的p1就是一個(gè) Promise 實(shí)例
- 所有異步任務(wù)都返回一個(gè) Promise 實(shí)例
- Promise 實(shí)例有一個(gè)then方法,用來指定下一步的回調(diào)函數(shù)
//原理
function f1(resolve, reject) {
// 異步代碼...
}
var p1 = new Promise(f1);
p1.then(f2); // f1的異步操作執(zhí)行完成,就會(huì)執(zhí)行f2。
- Promise 使得異步流程可以寫成同步流程
// 傳統(tǒng)寫法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
});
// Promise 的寫法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
let p = new Promise(function (resolve,reject){
//異步代碼
//resolve - 成功
//reject - 失敗
$.ajax({
url:'',
dataType:'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
})
})
//當(dāng)Promise執(zhí)行有結(jié)果了,就執(zhí)行此函數(shù)
p.then(function(arr){
//成功操作...
},function(err){
//失敗操作...
})
- Promise.all(promiseArray)方法
- 將多個(gè)Promise對(duì)象實(shí)例包裝,生成并返回一個(gè)新的Promise實(shí)例
- promise數(shù)組中所有的promise實(shí)例都變?yōu)閞esolve的時(shí)候,該方法才會(huì)返回
- 并將所有結(jié)果傳遞results數(shù)組中
- promise數(shù)組中任何一個(gè)promise為reject的話,則整個(gè)Promise.all調(diào)用會(huì)立即終止,并返回一個(gè)reject的新的promise對(duì)象
//用到點(diǎn)上
let p1 = new Promise(function (resolve,reject){
//異步代碼
//resolve - 成功
//reject - 失敗
$.ajax({
url:'',
dataType:'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
})
})
let p2 = new Promise(function (resolve,reject){
//異步代碼
//resolve - 成功
//reject - 失敗
$.ajax({
url:'',
dataType:'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
})
})
Promise.all([
p1,p2
]).then(function(arr){
//arr為兩次ajax的結(jié)果組成的數(shù)據(jù)
//全部成功操作...
},function(err){
//至少有一個(gè)失敗后操作...
})
//簡化
function createPromise(url){
return new Promise (function(resolve,reject){
$.ajax({
url,
dataType:'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
})
})
}
Promise.all([
createPromise('url1'),
createPromise('url2')
]).then(function(arr){
//arr為兩次ajax的結(jié)果組成的數(shù)據(jù)
//全部成功操作...
},function(err){
//至少有一個(gè)失敗后操作...
})
//高版本jq自帶支持Promise,不需要我們自己封裝函數(shù),精簡成
Promise.all([
$.ajax({url:'url1',dataType:'json'}),
$.ajax({url:'url2',dataType:'json'})
]).then(function(res){
//arr為兩次ajax的結(jié)果組成的數(shù)據(jù)
//全部成功操作...
let [arr,json] = res;
},function(err){
//至少有一個(gè)失敗后操作...
})
- Promise.rece([p1, p2, p3])
- Promse.race就是賽跑的意思
- 哪個(gè)結(jié)果獲得的快,就返回那個(gè)結(jié)果
- 不管結(jié)果本身是成功狀態(tài)還是失敗狀態(tài)
Promise.rece([
$.ajax({url:'url1',dataType:'json'}),
$.ajax({url:'url2',dataType:'json'})
])
generator-認(rèn)識(shí)生成器函數(shù)
-
generator生成器函數(shù)- 普通函數(shù),一路到底
-
generator函數(shù),中間可以停,到哪停呢,用yield配合,交出執(zhí)行權(quán) -
yield有 放棄、退讓、退位的意思 - 需要調(diào)用
next()方法啟動(dòng)執(zhí)行,需要遇到 yield 停, 踹一腳走一步 -
generator函數(shù)前面加一個(gè)*兩邊可以有空格,或靠近函數(shù)或function - 不能縮寫function成箭頭函數(shù)
- 背后實(shí)際生成多個(gè)小函數(shù),實(shí)現(xiàn)走走停停
//普通函數(shù)
function show(){
alert('a');
alert('b');
}
//generator函數(shù)
function * show(){
alert('a');
yield,
alert('b');
}
let genObj = show();
genObj.next();//彈出a,遇到y(tǒng)ield停止運(yùn)行
genObj.next();//彈出b
genObj.next();// 最后了,沒有結(jié)果
generator-yield是啥
-
yield- 既可傳參,又可以返回
- 第一個(gè)
next()傳參無效,只用來啟動(dòng)
- 如果函數(shù)前漏掉
*- 就是普通函數(shù)
- 如果有
yield會(huì)報(bào)錯(cuò),ReferenceError: yield is not defined -
yield只能在Generator函數(shù)內(nèi)部使用
//yield 傳參
function * show(){
alert('a');
let a = yield;
alert('b');
alert('a');
}
var gen = show()
gen.next() //彈出a
gen.next() //彈出b 和 undefined 因?yàn)闆]有傳參,yield沒有返回值
let gen = show();
gen.next(12);//彈出a 第一次執(zhí)行到y(tǒng)ield,但沒有執(zhí)行賦值
gen.next(4);//彈出b,彈出5
//yield 返回
function * show(){
alert("a");
yield 12;
alert('b');
return 55;
}
let gen = show();
let res1 = gen.next();
console.log(res1);//{value:12,done:false}
let res2 = gen.next();
//無return時(shí)
console.log(res2);//{value:undefined,done:true}
//有return時(shí)
console.log(res2);//{55,done:true}
generator-實(shí)例
- 異步操作處理
- 回調(diào)
- Promise 適合一次讀一組
- generator 適合邏輯性的
//npm i runner
runner(function * (){
let data1 = yield $.ajax({url:'url1',dataType:'json'});
let data2 = yield $.ajax({url:'url2',dataType:'json'});
let data3 = yield $.ajax({url:'url3',dataType:'json'});
})
console.log(data1,data2,data3);
//帶邏輯-普通回調(diào)
$.ajax({url:'url1',dataType:'json'},success(userData){
if(userData == 'vip'){
$.ajax({url:'url1',dataType:'json'},success(item){
//系列操作...
},error(err){
console.log(err);
})
}
})
//帶邏輯-Promise (比普通的回調(diào)更麻煩)
Promise.all([ $.ajax({url:'url1',dataType:'json'})
]).then(res => {
let userData = res[0];
if(userData == 'vip'){
Promise.all([
$.ajax({url:'url1',dataType:'json'})
]).then(res => {
},err => {
console.log(err);
})
}
},err => {
console.log(err);
})
// 帶邏輯-generator
runner(function * () {
let userData = yield $.ajax({url: 'getUserData'})
if (userData.type == 'VIP') {
let items = yield $.ajax({url: 'getVIPItems'})
} else {
let items = yield $.ajax({url: 'getItems'})
}
})
// yield 實(shí)例,用同步方式寫異步
server.use(function * () {
let data = yield db.query(`select * from user_table`)
this.body = data
})
ES7 預(yù)覽
- 數(shù)組
arr.includes()數(shù)組是否包含某個(gè)東西數(shù)組的 arr.keys(), arr.values(),arr.entries()
for ... in 遍歷數(shù)組 下標(biāo) key 能用于json
for ... of 遍歷數(shù)組 值 value, 不能用于json
keys 所有的key拿出來
values 所有的values拿出來
entries 所有的key-value對(duì)拿出來
let arr = ['a', 'b', 'c']
console.log(arr.includes(1))//false
for (let i in arr) {
console.log(i) // 循環(huán)的時(shí)下標(biāo) key
}
for (let i of arr) {
console.log(i) // 循環(huán)的是值 value
}
for (let i of arr.keys()) {
console.log('>'+i)
}
for (let i of arr.values()) {
console.log('>'+i)
}
for (let [key, value] of arr.entries()) {
console.log('>' + key + value)
}
let json = { a: 12, b: 5, c: 7 }
for (let i in json) {
console.log(i)
}
冪 **
3**8:3的8次方-
字符串
- padStart()/padEnd() 指定寬度,不夠就補(bǔ)空格或指定字符
console.log('=' + 'abcd'.padStart(6, '0') + '=')//=00abcd=
console.log('=' + 'abcd'.padEnd(6, '0') + '=')//=abcd00=
-
容忍度
- [1, 2, 3,] 老版數(shù)組最后不能有逗號(hào),新的可以有
- 函數(shù)參數(shù)最后多的逗號(hào)也可以
-
async await
- 和 generator yield 類似
- generator 不可以寫成箭頭函數(shù), async 可以
- 不依賴外部runner,標(biāo)準(zhǔn)統(tǒng)一,性能提高
async function show() {
console.log(1)
await
console.log(2)
}
async function readData(){
let data1 = await $.ajax({url:'url1',dataType:'json'});
let data2 = await $.ajax({url:'url1',dataType:'json'});
let data3 = await $.ajax({url:'url1',dataType:'json'});
console.log(data1,data2,data3);
}
//簡寫
async () => {
let data1 = await $.ajax({url:'url1',dataType:'json'});
let data2 = await $.ajax({url:'url1',dataType:'json'});
let data3 = await $.ajax({url:'url1',dataType:'json'});
console.log(data1,data2,data3);
}