1.ES5和ES6聲明變量的方式對比
ES5中聲明變量:var
1可以重復(fù)聲明
2無法限制修改
3沒有塊級作用域
ES6中聲明變量:let const
let 不能重復(fù)聲明,變量-可以修改, 塊級作用域
const 不能重復(fù)聲明,常量-不能修改, 塊級作用域
對于塊級作用域用什么好處,以下舉一個例子
//在ES6中沒有塊級作用域的情況下,以下按鈕點擊任何一個按鈕都只會彈出最后一位
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function (){
var aBtn = document.getElementsByTagName('input');
for(var i=0;i<aBtn.length;i++){
aBtn[i].onclick = function(){
alert(i)
}
}
}
</script>
</head>
<body>
<input type="button" name="" id="" value="按鈕1" />
<input type="button" name="" id="" value="按鈕2" />
<input type="button" name="" id="" value="按鈕3" />
</body>
</html>
//在沒有用ES6之前解決辦法就是以下處理,利用函數(shù)作為一級作用域,不過就是有點麻煩
for(var i=0;i<aBtn.length;i++){
(function(i){
aBtn[i].onclick = function(){
alert(i)
};
})(i);
}
//直接用let的就可以快速解決這類問題
for(let i=0;i<aBtn.length;i++){
(function(i){
aBtn[i].onclick = function(){
alert(i)
};
})(i);
}
2.ES6 中箭頭函數(shù)
ES6 中函數(shù)式聲明方式被箭頭函數(shù) => 取代
箭頭函數(shù):使用 => 定義函數(shù)
1.如果只有一個參數(shù),( )可以省
2.如果只有一個return,{ }可以省
//簡寫前
let show = (a) =>{
return a*2;
};
alert(show(12)); //24
//簡寫后
let show = a => a*2;
alert(show(12)); //24
//兩個參數(shù)時()不能省
let show = (a,b) => a+b;
alert(show(1,2)); //3
3.函數(shù)的參數(shù)
- 參數(shù)的擴(kuò)展/展開
- 默認(rèn)參數(shù)
參數(shù)擴(kuò)展:
1.收集剩余參數(shù)
//*Rest Parameter必須是最后一個,也就是以下代碼中的args參數(shù)
function show(a,b,...args){
alert(args);
}
show(12,14,1,2,3); // a=12 b=14 args=1,2,3
//如果args不是在最后一個,會報錯
function show(a,b,...args,c){
alert(args);
}
show(12,14,1,2,3);
//Uncaught SyntaxError: Rest parameter must be last formal parameter
2.展開數(shù)組
展開后的效果,跟直接把數(shù)組的內(nèi)容寫在這兒一樣
let arr1 = [1,2,3];
console.log(arr1); //[1, 2, 3]
console.log(...arr1); //1 2 3
//也可以用在合并兩個數(shù)組中
let arr2 = [4,5,6];
let arr = [...arr1,...arr2];
console.log(arr); //[1, 2, 3, 4, 5, 6]
//函數(shù)中也可以使用
function show(...args){
fn(...args)
}
function fn(a,b){
console.log(a+b);
}
show(1,2); //3
注意,不可以用在賦值上,以下代碼就是直接賦值就報以下錯誤
Uncaught SyntaxError: Unexpected token '...'
let a;
let arr = [1,2,3];
a = ...arr;
console.log(a);
默認(rèn)參數(shù):
就是有一默認(rèn)值,可傳可不傳
$('#div').animate({width: '200px'});
$('#div').animate({width: ''200px},1000);
4.ES6 中解構(gòu)賦值
- 左右兩邊結(jié)構(gòu)必須一樣
- 右邊必須是個東西
- 聲明和賦值不能分開(必修在一句話里完成)
let [a,b,c] = [1,2,3];
console.log(a,b,c); //1 2 3
let {e,f,g} = {a:12, c:5, d:22};
console.log(e,f,g); //12 5 22
let [{a1,a2},[n1,n2,n3],num,str] = [{a1:12,b1:5},[12,5,8],8,'kk'];
console.log(a1,a2,n1,n2,n3,num,str);//12 5 12 5 8 8 "kk"
如果結(jié)構(gòu)不一樣無法賦值,會報錯
let [a,b] = {a:12,b"12};
console.log(a,b);
//Uncaught SyntaxError: Identifier 'a' has already been declared
如果聲明跟賦值分開也一樣無法賦值,會報錯
let [a,b];
[a,b] = [12,22];
console.log(a,b);
//Uncaught SyntaxError: Identifier 'a' has already been declared
5.數(shù)組
- map ???????映射 ??一個對一個
- reduce ???匯總 ??一堆出來一個
- filter ????????過濾器
- forEach ??循環(huán)(迭代)
map
let arr = [12,5,8];
let result = arr.map(item => item*2)
console.log(result); //[24, 10, 16]
let score = [19,85,59,99];
let res = score.map(item => item>=60?'及格':'不及格');
console.log(res); //["不及格", "及格", "不及格", "及格"]
reduce
let arr = [1,2,3,4];
//tmp初始值, 或者計算結(jié)束后的返回值。
//item 當(dāng)前元素
//當(dāng)前元素的索引
let result = arr.reduce((tmp,item,index) => {
return tmp+item;
})
//一開始 tmp = arr[0] item = arr[1] index = 1
//后面tmp 會等于最后運算的結(jié)構(gòu),比如代碼中是執(zhí)行tmp+item
//所以第二次tmp = arr[0] + arr[1] = 3 item = arr[2] index = 2
console.log(result); //10
filter
let arr = [1,2,3,4,5,6];
let result = arr.filter(item => {
if(item%3 == 0){
return true;
}else{
return false;
}
})
console.log(result); //[3, 6]
forEach
let arr = [12,15,13,5];
arr.forEach((item,index) => {
console,log(item); //12 15 13 5
})
6.字符串
- 多了兩個新發(fā)法
startsWith
endsWith - 字符串模板
字符串連接
????i.直接把東西塞到字符串里面 ??????${東西}
??? ii.可以折行
//startsWith和endsWith用法
let str = 'https://www.baidu.com';
if(str.startsWith('https://')){
console.log('yes') //yes
}else{
console.log('no');
}
let email = '1002111759@qq.com'
if(email.endsWith('@qq.com')){
console.log('yes');
}else{
console.log('no');
}
//字符串連接
let title = '標(biāo)題';
let content '內(nèi)容';
let str = `<div>
<h1>${title}</h1>
<p>${content}</p>
</div>`
console.log(str);
7.ES6的面向?qū)ο?/h2>
class關(guān)鍵字、構(gòu)造器和類分開了
class里面直接加方法
class關(guān)鍵字、構(gòu)造器和類分開了
class里面直接加方法
首先先看一下老版的面向?qū)ο笠约袄^承
function User(name,pass){
this.name = name;
this.pass = pass;
}
User.prototype.showName = function (){
console.log(this.name);
}
User.prototype.showPass = function (){
console.log(this.pass);
}
var u1 = new User('kk','123456');
u1.showName(); //kk
u1.showPass(); //123456
//老版繼承
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('Flipped','123456',3);
v1.showName(); //Flipped
v1.showPass(); //123456
v1.showLevel(); //3
ES6面向?qū)ο笮聦懛?/p>
class User{
constructor(name,pass){
this.name = name;
this.pass = pass;
}
showName(){
console.log(this.name);
}
showPass(){
console.log(this.pass)
}
}
var u1 = new User('kk','123456');
u1.showName(); //kk
u1.showPass(); //123456
//ES6繼承
class VipUser extends User{
constructor(name,pass,level){
//super指代了整個prototype或者_(dá)_proto__指向的對象
// 用在構(gòu)造函數(shù)中,必須在使用this之前調(diào)用
super(name,pass);
this.level = level;
}
showLevel(){
console.log(this.level);
}
}
var v1 = new VipUser('Flipped','123456',3);
v1.showName(); //Flipped
v1.showPass(); //123456
v1.showLevel(); //3
面向?qū)ο髴?yīng)用---React
沒學(xué)過React可以跳過以下案例
React:
- 組件化 -- class ???一個組件就是一個class
- JSX ????JSX==babel==browser.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="react.js" charset="utf-8"></script>
<script src="react-dom.js" charset="utf-8"></script>
<script src="browser.js" charset="utf-8"></script>
<script type="text/babel">
class Item extends React.Component{
constructor(...args){
super(...args);
}
render(){
return <li>{this.props.str}</li>;
}
}
class List extends React.Component{
constructor(...args){
super(...args);
}
render(){
let aItems = this.props.arr.map(a => <Item str={a}></Item >);
//for(let i=0;i<this.props.arr.length;i++){
// aItems.push(<Item str={this.props.arr[i]}></Item >)
//}
return <ul>
{aItems}
</ul>;
}
}
window.onload = function (){
let oDiv = document.getElementById('div1');
ReactDOM.render(
<List arr = { ['Flipped','good'] }></List >,
oDiv;
);
}
</script>
</head>
<body>
<div id="div1">
</div>
</body>
8.JSON
JSON 格式
?JavaScript Object Notation 的縮寫,是一種用于數(shù)據(jù)交換的文本格式。JSON 是 JS對象的嚴(yán)格子集。
?JSON 的標(biāo)準(zhǔn)寫法:
??只能用雙引號
??所有的key都必須用雙引號包起來
JSON 對象
?JSON 對象是 JavaScript 的原生對象,用來處理 JSON 格式數(shù)據(jù),有兩個靜態(tài)方法:
??JSON.parse(string) :接受一個 JSON 字符串并將其轉(zhuǎn)換成一個 JavaScript 對象。
??JSON.stringify(obj) :接受一個 JavaScript 對象并將其轉(zhuǎn)換為一個 JSON 字符串。
let json={a:12,b:5};
//因為在作用與url當(dāng)作參數(shù)傳遞的時候,如參數(shù)出現(xiàn)空格這樣的特殊字段,
//后臺只可以讀取到空格前的內(nèi)容,后面內(nèi)容丟失,造成數(shù)據(jù)讀取失敗,
//但是如果用encodeURIComponent()包裹一下,那會將這些特殊字符進(jìn)行轉(zhuǎn)義,
//這樣后臺就可以成功讀取了,所以encodeURIComponent()用于url作為參數(shù)傳遞的場景中使用
let str='https://www.baidu.com?data='+encodeURIComponent(JSON.stringify(json));
alert(str);
let json={a:12,b:5};
alert(JSON.stringify(json)); //json轉(zhuǎn)字符串
let str = '{"a": 12, "b": 5, "c": "abc"}';
let json1 = JSON.parse(str); //字符串轉(zhuǎn)json
console.log(json1);
let a=12;
let b=5;
let json={a,b,c:55}; //名字和值一樣,可以只寫一個
console.log(json);
let json={
a:12,
/*show: function () {//舊寫法
alert(this.a);
}*/
show() {
alert(this.a);
}
};
json.show();
9.ES6的Promise
promise:為了解決異步編程中的回調(diào)地獄而產(chǎn)生
- 異步:操作直接沒啥關(guān)系,同時進(jìn)行多個操作,回調(diào)嵌套多個就會產(chǎn)生回調(diào)地獄
- 同步:同時只能做一件事
基本用法
Promise 對象是由關(guān)鍵字 new 及其構(gòu)造函數(shù)來創(chuàng)建的。
首先,介紹一下如何創(chuàng)建一個 Promise;
// 方法1
let promise = new Promise ( (resolve, reject) => {
if ( success ) {
resolve(res) // pending ——> resolved 參數(shù)將傳遞給對應(yīng)的回調(diào)方法
} else {
reject(err) // pending ——> rejectd
}
} )
// 方法2
function promise () {
return new Promise ( function (resolve, reject) {
if ( success ) {
resolve(res)
} else {
reject(err)
}
} )
}
該構(gòu)造函數(shù)接收兩個函數(shù)作為參數(shù),分別是resolve和reject。
當(dāng)異步操作執(zhí)行成功后,會將異步操作結(jié)果作為參數(shù)傳入resolve函數(shù)并執(zhí)行;失敗則會將異步操作的錯誤作為參數(shù)傳入reject函數(shù)并執(zhí)行;
然后通過then方法,分別指定resolved狀態(tài)和rejected狀態(tài)的回調(diào)函數(shù)。
promise.then(function(value) {
// 成功
}, function(error) {
// 失敗
});
.catch()的作用是捕獲Promise的錯誤,與then()的rejected回調(diào)作用幾乎一致。但是由于Promise的拋錯具有冒泡性質(zhì),能夠不斷傳遞,這樣就能夠在下一個catch()中統(tǒng)一處理這些錯誤。同時catch()也能夠捕獲then()中拋出的錯誤,所以建議不要使用then()的rejected回調(diào),而是統(tǒng)一使用catch()來處理錯誤
promise.then(
(value) => {
//成功
}
).catch(
(err) => {
//失敗
}
)
Promise方法
(1) Promise.all()
Promise的all方法提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完后才執(zhí)行回調(diào)。
//如果傳入的參數(shù)中存在不是Promise實例,則會先調(diào)用Promise.resolve,
//將其轉(zhuǎn)為Promise實例,再進(jìn)一步處理。
var a1 = Promise.resolve('kk');
var a2 = 'is';
var a3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'good');
});
Promise.all([a1, a2, a3]).then(values => {
console.log(values);
});
// ["kk", "is", "good"]
(2) Promise.race()
Promise.race 的使用
race有賽跑之譯,因此返回的新實例狀態(tài),是跟隨參數(shù)中最先改變狀態(tài)的那個實例;如果不是Promise實例,依舊先用Promise.resolve方法,轉(zhuǎn)化后再進(jìn)一步處理。
如果傳的迭代為空,則返回的 Promise 永遠(yuǎn)等待
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, '第一個請求');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(reject, 200, '第二個請求');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
}, function(err) {
console.log(err);
});
// 第一個請求
(3)Promise.resolve() / Promise.reject()
用來包裝一個現(xiàn)有對象,將其轉(zhuǎn)變?yōu)镻romise對象,但Promise.resolve()會根據(jù)參數(shù)情況返回不同的Promise:
參數(shù)是Promise:原樣返回
參數(shù)帶有then方法:轉(zhuǎn)換為Promise后立即執(zhí)行then方法
參數(shù)不帶then方法、不是對象或沒有參數(shù):返回resolved狀態(tài)的Promise
Promise.reject()會直接返回rejected狀態(tài)的Promise
10.ES6的generator - 生成器
普通函數(shù)--一路到底
generator函數(shù)--中間能停
function *show(){
alert('a');
yield;//放棄執(zhí)行的權(quán)利,先暫時不往下走
alert('b');
}
let genObj = show();
genObj.next(); //沒有next不會執(zhí)行函數(shù)下一步
genObj.next();
yield:可以傳參和返回
//yield傳參
function *show(){
alert('a');
let a = yield;
alert('b');
alert(a); //5
}
let genObj = show();
genObj.next(12); //沒法給yield傳參,只執(zhí)行到y(tǒng)ield前面的代碼
genObj.next(5);
//yield返回
function *show(){
alert('a');
yield 12;
alert('b');
return 44;//沒有return的話res2的value值為undefined
}
let genObj = show();
let res1 = genObj.next();
console.log(res1); //{ done: false, value: 12 }
let res2 = genObj.next();
console.log(res2); //{ done: true, value: 44 }
通俗化就是以下偽代碼
function *炒菜(菜市場買回來的){
洗菜 -> 洗好的菜;
let 干凈的菜 = yield 洗好的菜;
干凈的菜 ->切->絲
let 切好的菜 = yield 絲;
切好的菜->炒->熟的菜
return 熟的菜;
}
ES7 & ES8
1.數(shù)組 includes
數(shù)組是否包含某個東西
includes()作用,是查找一個值在不在數(shù)組里,若是存在則返回true,不存在返回false.
2.數(shù)組 keys/values/entries
| 數(shù)組 | json | |
|---|---|---|
| for...in | 下標(biāo)(key) | 下標(biāo)(key) |
| for...of | 值(value) | 不能用在json |
key => 所有的key拿出來 ???????????????????????0,1,2,3
let arr = [12,5,7,99];
for(let key of arr.keys()){
console.log(key) //0 1 2 3
}
values => 所有的values拿出來 ??????????????12,5,7,99
let arr = [12,5,7,99];
for(let value of arr.values()){
console.log(value) //12,5,7,99
}
entries => 所有的key-value對拿出來 ?????{key:0, value: 12}, {key:1, value: 5}...
let arr = [12,5,7,99];
for(let entry of arr.entries()){
console.log(entry)
}
//{0:0,1: 12} {0:1, 1: 5} {0:2,1:7} {0:3,1:99}
3.冪
console.log(2**2) //4
4.padStart/padEnd
console.log('('+'abc'.padStart(10)+')'); //( abc)
console.log('('+'abc'.padStart(10,'0')+')'); //(0000000abc)
console.log('('+'abc'.padEnd(10)+')'); //(abc )
5.async await
async: 異步的意思??创a
async function testAsync() {
return "hello async";
}
console.log( testAsync() ) //輸出結(jié)果是 Promise {<pending>}并不是"hello async"
async 的作用是申明一個異步函數(shù),函數(shù)的返回值是promise 對象
即 async 函數(shù)返回的是一個 Promise 對象
await
await 是 async+wait 的結(jié)合 即異步等待,async和await 二者必須是結(jié)合著使用
await 是個運算符,用于組成表達(dá)式,await 表達(dá)式的運算結(jié)果取決于它等的東西。
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const a = await getSomething() // await 后面也可以不是promise對象
const b = await testAsync()
console.log(a, b); // 輸出結(jié)果是 “something hello async”
}
test()
注意:
如果它等到的不是一個 Promise 對象,那 await 表達(dá)式的運算結(jié)果就是它等到的東西。
如果它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞后面的代碼,等著 Promise 對象 resolve,然后得到 resolve 的值,作為 await 表達(dá)式的運算結(jié)果。