摘要:在年正式發(fā)布了,簡(jiǎn)稱(chēng),又稱(chēng)為。再次簡(jiǎn)寫(xiě)循環(huán)迭代數(shù)組每個(gè)元素都執(zhí)行一次回調(diào)函數(shù)。方法用于調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)。注意對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的。
轉(zhuǎn)載請(qǐng)注明出處
原文連接 http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d
es6 是什么首先弄明白ECMA和js的關(guān)系。ECMA是標(biāo)準(zhǔn),Javascript是ECMA的實(shí)現(xiàn)。因?yàn)閖s也是一種語(yǔ)言,但凡語(yǔ)言都有一套標(biāo)準(zhǔn),而ECMA就是javascript的標(biāo)準(zhǔn)。 在2015年正式發(fā)布了ECMAscript6.0,簡(jiǎn)稱(chēng)ES6,又稱(chēng)為ECMAscript2015。
歷史
ECMAScript和Javascript
ECMA是標(biāo)準(zhǔn),JS是實(shí)現(xiàn)
類(lèi)似于HTML5是標(biāo)準(zhǔn),IE10,Chrome,F(xiàn)F都是實(shí)現(xiàn)
換句話(huà)說(shuō),將來(lái)也能有其他XXXScript來(lái)實(shí)現(xiàn)ECMA
ECMAScript簡(jiǎn)稱(chēng)ECMA或ES
目前版本
低級(jí)瀏覽器主要支持ES 3.1
高級(jí)瀏覽器正在從ES 5過(guò)度ES 6
歷史版本
時(shí)間 | ECMA | JS | 解釋 |
---|---|---|---|
1996.11 | EC 1.0 | JS穩(wěn)定 | Netscript將js提交給ECMA組織,ES正式出現(xiàn) |
1998.06 | ES 2.0 | ES2正式發(fā)布 | |
1999.12 | ES 3.0 | ES3被廣泛接受 | |
2007.10 | ES 4.0 | ES4過(guò)于激進(jìn),被廢了 | |
2008.07 | ES 3.1 | 4.0退化為嚴(yán)重縮水版的3.1 因?yàn)槌车锰珔柡?,所以ES3.1代號(hào)為Harmony(和諧) |
|
2009.12 | ES 5.0 | ES5正式發(fā)布 同時(shí)公布了JavaScript.next也就是后來(lái)的ES6.0 |
|
2011.06 | ES 5.1 | ES5.1成為了ISO國(guó)際標(biāo)準(zhǔn) | |
2013.03 | ES 6.0 | ES6.0草案定稿 | |
2013.12 | ES 6.0 | ES6.0草案發(fā)布 | |
2015.06 | ES 6.0 | ES6.0預(yù)計(jì)發(fā)布正式版 JavaScript.next開(kāi)始指向ES 7.0 |
es5兼容性
http://kangax.github.io/compat-table/es5/
es6兼容性
http://kangax.github.io/compat-table/es6/
ES6(ES2015)-- IE10+,Chrome,F(xiàn)ireFox,移動(dòng)端,NodeJS。這些環(huán)境基本上都是認(rèn)得,都能兼容
但是有需求兼容ie怎么辦
有兩種辦法
比方說(shuō)在移動(dòng)端或者是混合開(kāi)發(fā)當(dāng)中,多去用用ES6,在老的版本中不用。惹不起咋躲得起。編譯,轉(zhuǎn)換
在線(xiàn)轉(zhuǎn)換
簡(jiǎn)單來(lái)說(shuō)就是寫(xiě)好了ES6了然后引用一個(gè)js庫(kù)進(jìn)來(lái)。我什么也不用做了。它替我去做了各種各樣的事情
缺點(diǎn),用戶(hù)每次打開(kāi)頁(yè)面都要重新轉(zhuǎn)換一遍,性能體驗(yàn)不是很好。
提前編譯
ES6的到底有什么樣的東西?
變量(對(duì)原有的變量做了修改)
函數(shù)(對(duì)原有的函數(shù)也做了修改)
數(shù)組(對(duì)數(shù)組做了一些改進(jìn))
字符串(改進(jìn))
面向?qū)ο?/p>
Promise(串行化的異步請(qǐng)求方式)
yield && generator(generator是專(zhuān)門(mén)把同步操作拆成異步操作,generator是對(duì)Promise的一個(gè)封裝)
模塊化
變量-let和const回顧ES5是怎么生明變量的,有什么樣的缺點(diǎn)
var的缺點(diǎn)
可以重復(fù)聲明
無(wú)法限制修改
沒(méi)有塊級(jí)作用域
可以重復(fù)聲明
最大的問(wèn)題
var a=12; var a=5; alert(a);//彈窗5
會(huì)發(fā)現(xiàn)5能出來(lái),沒(méi)有報(bào)錯(cuò),沒(méi)有警告,什么都沒(méi)有
這在其他語(yǔ)言是不可出現(xiàn)的。
無(wú)法限制修改
在程序中,有些東西是永遠(yuǎn)不變的。
比方說(shuō)常量
PI=3.1415926
是不會(huì)發(fā)生改變
在很多語(yǔ)言中都有常量的概念。在js中沒(méi)有
至少var不是一個(gè)常量。
換句話(huà)說(shuō),要不要改,能不能讓別人別動(dòng)這個(gè)值,不要改這個(gè)值。全憑自覺(jué)。
為什么java是全世界最流行的一門(mén)語(yǔ)言
原因很簡(jiǎn)單,因?yàn)樗浅5膰?yán)謹(jǐn),他非常的死板。
相信一件事,越是容易的語(yǔ)言,越是簡(jiǎn)單的語(yǔ)言。實(shí)際上是不嚴(yán)謹(jǐn)。就沒(méi)法去開(kāi)發(fā)大型項(xiàng)目
反過(guò)來(lái)他可能讓你覺(jué)得很難受的語(yǔ)言java,對(duì)你限制很?chē)?yán)格。但是你掌握了呀之后,開(kāi)發(fā)起大型應(yīng)用會(huì)非常的得心應(yīng)手。
沒(méi)有塊級(jí)作用域
es5 只在函數(shù)中支持塊級(jí)作用域
{ //這就是語(yǔ)法塊 } if(){ 變量=xxxx } //變量出來(lái)就用不了了,這就是塊作用域 for(){ }
體現(xiàn)塊級(jí)作用域作用
if(true){ var a=12; } alert(a); //在塊級(jí)作用域內(nèi)聲明變量。在外部依然能夠訪(fǎng)問(wèn)
在ES6中有了兩種新的定義變量的方式
let和const
let
不能重復(fù)聲明,let是變量,可以修改,塊級(jí)作用域
塊級(jí)作用域
可修改let變量的值
const
不可重復(fù)聲明,const常量,不能修改,塊級(jí)作用域
塊級(jí)作用域
不可修改const變量的值
let 不能重復(fù)聲明例子
let a=12; let a=5; console.log(a); //報(bào)錯(cuò) //Uncaught SyntaxError: Identifier "a" has already been declared //不能重復(fù)聲明
const 不能重復(fù)聲明例子
const a=12; const a=5; console.log(a); //報(bào)錯(cuò) //Uncaught SyntaxError: Identifier "a" has already been declared //不能重復(fù)聲明
在大型項(xiàng)目中,重復(fù)聲明這件事,指不定你定義了什么東西別人也定義了。還不報(bào)錯(cuò),到時(shí)候定位bug很難找。
變量和常量
變量
let a=12;//聲明變量賦值 a=5;//給變量a賦值 console.log(a);//你會(huì)明確的發(fā)現(xiàn)它變成了5
常量
const a=12; a=5; console.log(a);
報(bào)錯(cuò),不能對(duì)常量賦值
塊級(jí)作用域
var 塊級(jí)作用域只在函數(shù)中體現(xiàn),也就是說(shuō)在函數(shù)中var聲明的變量不會(huì)在全局作用域中體現(xiàn)
function aa(){ var a=1; console.log(a) } aa(); console.log(a)
let和const只在塊級(jí)作用域,或者在語(yǔ)法塊之內(nèi)起作用
if(true){ let a=12; } console.log(a);//Uncaught ReferenceError: a is not defined
if(true){ const a=12; } console.log(a);//Uncaught ReferenceError: a is not defined
語(yǔ)言推出一個(gè)新的版本,一個(gè)更好的版本,他一定是要解決一些原來(lái)有的問(wèn)題,ES6也不例外。
塊級(jí)作用域有什么
Document
以上代碼執(zhí)行,不管按哪個(gè)按鈕彈出都是3
由于var聲明變量只在函數(shù)作用域中擴(kuò)散到全局
在for或者if快級(jí)作用域中聲明的變量會(huì)在局部或全局生效
當(dāng)for循環(huán)執(zhí)行完畢,i這個(gè)變量暴露到全局了,等于3
所以for循環(huán)中執(zhí)行的事件綁定,是將點(diǎn)擊事件回調(diào)函數(shù)執(zhí)行。當(dāng)點(diǎn)擊按鈕時(shí)候,會(huì)出發(fā)綁定回調(diào)函數(shù),此時(shí)當(dāng)前作用域中,i等于3,所以無(wú)論點(diǎn)擊哪個(gè)按鈕彈出都是3
以前我們是通過(guò)閉包解決這個(gè)問(wèn)題
Document
在每一層循環(huán)的時(shí)候,用一個(gè)匿名函數(shù)而且是立即執(zhí)行的匿名函數(shù)給他包裝起來(lái),然后將每一次遍歷的1.2.3分別的值去傳到這個(gè)匿名函數(shù)里,然后匿名函數(shù)接到這個(gè)參數(shù)i再放到點(diǎn)擊事件中去引用i當(dāng)我們每次點(diǎn)擊事件輸出的值i就會(huì)取每一個(gè)閉包環(huán)境下的i。所以這樣就能達(dá)到效果。
使用let來(lái)實(shí)現(xiàn)
Document
for循環(huán)本身就是一個(gè)語(yǔ)法塊,自身就是一個(gè)塊
由于var只把函數(shù)作為作用域
所以以上需要通過(guò)立即執(zhí)行函數(shù)來(lái)包一層,來(lái)實(shí)現(xiàn)效果。
而let本身是支持塊級(jí)作用域的,所以電腦按鈕執(zhí)行回掉函數(shù),打印i,是當(dāng)前塊級(jí)作用域下的i
這個(gè)i在非for塊作用域下是未定義的。
函數(shù)-箭頭函數(shù)箭頭函數(shù)在寫(xiě)法上對(duì)es5做了一些修整,代碼看起來(lái)更顯得簡(jiǎn)潔
如果只有一個(gè)參數(shù),圓括號(hào)"()"可以省略
函數(shù)體如果只有一句return語(yǔ)句,花括號(hào)也可以省略
// 定義一個(gè)箭頭函數(shù) let a = (arg)=>{ // 這里=>符號(hào)就相當(dāng)于function關(guān)鍵字 return arg+=1 } // 也可以簡(jiǎn)寫(xiě)為 let a = arg => arg+=1
箭頭函數(shù)的作用跟以前接觸的函數(shù)沒(méi)什么本質(zhì)的區(qū)別,更多的是一種寫(xiě)法上的變化。
function show() { } 同等于 let show =()=>{ }
function () { } 同等于 ()=>{ }
Document 同等于Document
箭頭函數(shù)也對(duì)this的指向做了修整 es6之前的函數(shù)的this指向調(diào)用函數(shù)時(shí)所在的對(duì)象,而箭頭函數(shù)的this指向函數(shù)定義時(shí)所在的對(duì)象
//普通函數(shù) var obj = { say: function () { setTimeout(function() { console.log(this) }); } } obj.say();//Window?object
// 箭頭函數(shù) var obj = { say: function () { setTimeout(() => { console.log(this) }); }, test:123 } obj.say(); // obj函數(shù)-參數(shù)
參數(shù)擴(kuò)展/數(shù)組展開(kāi)
默認(rèn)參數(shù)
參數(shù)擴(kuò)展
收集剩余參數(shù)
ES6 引入 rest 參數(shù)(形式為...變量名),用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對(duì)象了。rest 參數(shù)搭配的變量是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中。
function show (a,b,...args){ console.log(a);//1 console.log(b);//2 console.log(args);//[3,4,5,6] } show(1,2,3,4,5,6);
下面是一個(gè) rest 參數(shù)代替arguments變量的例子。
// arguments變量的寫(xiě)法 function sortNumbers() { return Array.prototype.slice.call(arguments).sort(); } // rest參數(shù)的寫(xiě)法 const sortNumbers = (...numbers) => numbers.sort();
展開(kāi)數(shù)組
展開(kāi)后的效果,跟直接把數(shù)組內(nèi)容寫(xiě)在這一樣
let arr=[1,2,3]; console.log(1,2,3); console.log(...arr); //1,2,3同等于...arr
function show(a,b,c){ console.log(a) console.log(b) console.log(c) } let arr=[1,2,3]; show(1,2,3); show(...arr); //1,2,3同等于...arr
let arr1=[1,2,3]; let arr2=[4,5,6]; let arr=[...arr1,...arr2]; let arrS=[1,2,3,4,5,6]; //...arr1,寫(xiě)法,相當(dāng)于將數(shù)組內(nèi)容掏出來(lái)內(nèi)容
默認(rèn)參數(shù)
function show(a,b=5,c=6){ //我希望b,默認(rèn)是5 不傳的時(shí)候 //我希望c,默認(rèn)是6 不傳的時(shí)候 console.log(a,b,c);//1,2,6 } show(1,2);解構(gòu)賦值
允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值,這被稱(chēng)為解構(gòu)。比如:
var [a,b] = [1,2] // a=1 b=2
左右兩邊結(jié)構(gòu)必須一樣
右邊必須是個(gè)合法的數(shù)據(jù)
聲明和賦值必須一句話(huà)完成,不能把聲明與賦值分開(kāi)
let [a, b] = [1, 2] // 左右都是數(shù)組,可以解構(gòu)賦值 let {a, b} = {a:1, b:2} // 左右都是對(duì)象,可以解構(gòu)賦值 let [obj, arr] = [{a:1}, [1, 2]] // 左右都是對(duì)象,可以解構(gòu)賦值 let [a, b] = {a:1, b:2} // err 左右結(jié)構(gòu)不一樣,不可以解構(gòu)賦值 let {a,b} = {1, 2} // err 右邊不是一個(gè)合法的數(shù)據(jù),不能解構(gòu)賦值 let [a, b]; [a, b] = [1, 2] // err 聲明與賦值分開(kāi),不能解構(gòu)賦值數(shù)組
數(shù)組擴(kuò)展了4個(gè)方法:map、reduce、filter、forEach
map 映射
通過(guò)指定函數(shù)處理數(shù)組的每個(gè)元素,并返回處理后的數(shù)組。
一個(gè)對(duì)一個(gè)
[12,58,99,86,45,91] [不及格,不及格,及格,及格,不及格,及格] //將數(shù)組映射成另一個(gè)數(shù)組
[45,57,135,28] //將用戶(hù)id映射成對(duì)象 [ {name:"huang",role:1}, {name:"huang1",role:2}, {name:"huang2",role:3}, {name:"huang4",role:1} ]
map例子
let arr=[12,5,8]; //我想要將數(shù)組內(nèi)容乘與2的結(jié)果 let result=arr.map(function(item){ console.log(item); //需要將你要的內(nèi)容返回出來(lái) return item*2; }); console.log(arr);//[12, 5, 8] console.log(result);//[24, 10, 16]
簡(jiǎn)寫(xiě)1
let arr=[12,5,8]; //我想要將數(shù)組內(nèi)容乘與2的結(jié)果 let result=arr.map(item=>{ console.log(item); //需要將你要的內(nèi)容返回出來(lái) return item*2; }); console.log(arr);//[12, 5, 8] console.log(result);//[24, 10, 16]
簡(jiǎn)寫(xiě)2
let arr=[12,5,8]; //我想要將數(shù)組內(nèi)容乘與2的結(jié)果 let result=arr.map(item=>item*2); console.log(arr);//[12, 5, 8] console.log(result);//[24, 10, 16]
let arr=[12,58,99,86,45,91] let result=arr.map(item=>item>=60?"及格":"不及格"); console.log(arr);//[12, 58, 99, 86, 45, 91] console.log(result);//["不及格", "不及格", "及格", "及格", "不及格", "及格"]
reduce 匯總
將數(shù)組元素計(jì)算為一個(gè)值(從左到右)。
一堆出一個(gè)
算個(gè)總數(shù)
let arr=[12,58,99,86,45,91] /** * [description] * @param {[type]} (total,currentValue,index,arr [ * 初始值, 或者計(jì)算結(jié)束后的返回值。 * 當(dāng)前元素 * 當(dāng)前元素的索引 * 當(dāng)前元素所屬的數(shù)組對(duì)象。 * ] * @return {[type]} [返回計(jì)算結(jié)果] */ let result=arr.reduce((total,currentValue,index,arr)=>{ return total+currentValue; }); console.log(result)//391
算個(gè)平均數(shù)
let arr=[12,58,99,86,45,91] /** * [description] * @param {[type]} (total,currentValue,index,arr [ * 初始值, 或者計(jì)算結(jié)束后的返回值。 * 當(dāng)前元素 * 當(dāng)前元素的索引 * 當(dāng)前元素所屬的數(shù)組對(duì)象。 * ] * @return {[type]} [返回計(jì)算結(jié)果] */ let result=arr.reduce((total,currentValue,index,arr)=>{ if(index!=arr.length-1){ //如果不是最后一次 return total+currentValue; //求和 }else{ //最后一次 return (total+currentValue)/arr.length; //求和再除于長(zhǎng)度個(gè)數(shù) } }); console.log(result)//65.16666666666667
filter 過(guò)濾器
檢測(cè)數(shù)值元素,并返回符合條件所有元素的數(shù)組。
定義和用法
filter() 方法創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是通過(guò)檢查指定數(shù)組中符合條件的所有元素。
注意: filter() 不會(huì)對(duì)空數(shù)組進(jìn)行檢測(cè)。
注意: filter() 不會(huì)改變?cè)紨?shù)組。
需求,能被3整除的留下,不能的去除
let arr=[12,58,99,86,45,91] //需求,能被3整除的留下,不能的去除 /** * [description] * @param {[type]} (currentValue,index,arr [ * 當(dāng)前元素的值 * 當(dāng)前元素的索引值 * 當(dāng)前元素屬于的數(shù)組對(duì)象 * ] * @return {[type]} [返回?cái)?shù)組,包含了符合條件的所有元素。如果沒(méi)有符合條件的元素則返回空數(shù)組。] */ let result=arr.filter((currentValue,index,arr)=>{ if(currentValue%3==0){ return true; }else{ return false; } }); console.log(result)//[12, 99, 45]
簡(jiǎn)寫(xiě)
let arr=[12,58,99,86,45,91] //需求,能被3整除的留下,不能的去除 /** * [description] * @param {[type]} (currentValue,index,arr [ * 當(dāng)前元素的值 * 當(dāng)前元素的索引值 * 當(dāng)前元素屬于的數(shù)組對(duì)象 * ] * @return {[type]} [返回?cái)?shù)組,包含了符合條件的所有元素。如果沒(méi)有符合條件的元素則返回空數(shù)組。] */ let result=arr.filter((currentValue,index,arr)=>{ return currentValue%3==0; }); console.log(result)//[12, 99, 45]
再次簡(jiǎn)寫(xiě)
let arr=[12,58,99,86,45,91] let result=arr.filter(currentValue=>currentValue%3==0); console.log(result)//[12, 99, 45]
forEach 循環(huán)(迭代)
數(shù)組每個(gè)元素都執(zhí)行一次回調(diào)函數(shù)。
forEach() 方法用于調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)。
注意: forEach() 對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的。
字符串多了兩個(gè)新方法
字符串模板
多了兩個(gè)新方法
startsWith() 表示參數(shù)字符串是否在原字符串的頭部,返回布爾值
startsWith應(yīng)用
let str="http://blog.huanghanlian.com" if(str.startsWith("http://")){ console.log("普通網(wǎng)址"); }else if(str.startsWith("https://")){ console.log("加密網(wǎng)址"); }else if(str.startsWith("git://")){ console.log("git網(wǎng)址"); }else if(str.startsWith("svn://")){ console.log("svn網(wǎng)址"); }else{ console.log("其他") }
endsWith() 表示參數(shù)字符串是否在原字符串的尾部,返回布爾值
let str="http://blog.huanghanlian.com/sitemap.xml" if(str.endsWith(".xml")){ console.log("網(wǎng)站地圖"); }else if(str.endsWith(".jpg")){ console.log("圖片"); }else if(str.endsWith(".txt")){ console.log("文本文件"); }else{ console.log("其他") } //網(wǎng)站地圖
includes() 表示是否在原字符串找到了參數(shù)字符串,返回布爾值
字符串模板
模板字符串有兩個(gè)能力
能直接把變量塞到字符串中去。
可以折行
平常寫(xiě)字符串有兩種寫(xiě)法,
let str="abc"; let str2="efg";
一種是單引號(hào),一種是雙引號(hào)。在js里都能用。沒(méi)什么區(qū)別
現(xiàn)在出來(lái)一種新的字符串
let str=`abc`;
這種符號(hào)叫反單引號(hào)
簡(jiǎn)單使用例子
let a=12; let str=`a${a}bc`; console.log(str);//a12bc
反單引號(hào)中的美元符號(hào)帶上花括號(hào)他的作用就是把變量直接塞進(jìn)字符串里面去。
例子
以前字符串拼接
let title="我是標(biāo)題"; let content="我是內(nèi)容"; let str=""; document.body.innerHTML=str; console.log(str);"+title+"
"+content+"
有了字符串模板后的寫(xiě)法
let title="我是標(biāo)題"; let content="我是內(nèi)容"; let str="面向?qū)ο?基礎(chǔ)"; let str2=`"+title+"
"+content+"
`; document.body.innerHTML=str2; console.log(str2);${title}
${content}
面向?qū)ο?/strong>
es5面向?qū)ο?/p>
function User(name,pass){ this.name=name; this.pass=pass; } //給這個(gè)類(lèi)加原型方法 /** * [showName 獲取用戶(hù)名] * @return {[type]} [返回用戶(hù)名] */ User.prototype.showName=function(){ console.log(this.name); return this.name; }; /** * [showPass 獲取用戶(hù)密碼] * @return {[type]} [返回用戶(hù)密碼] */ User.prototype.showPass=function(){ console.log(this.pass); return this.pass; }; var ul=new User("黃繼鵬","abc"); //調(diào)用類(lèi)方法 ul.showName();//黃繼鵬
這樣寫(xiě)的缺點(diǎn)
類(lèi)和構(gòu)造函數(shù)不分,
類(lèi)散開(kāi)了,先聲明一個(gè)構(gòu)造函數(shù),然后對(duì)函數(shù)原型添加方法
ES6 提供了更接近傳統(tǒng)語(yǔ)言的寫(xiě)法,引入了 Class(類(lèi))這個(gè)概念,作為對(duì)象的模板。通過(guò)class關(guān)鍵字,可以定義類(lèi)。 先看如何定義一個(gè)class類(lèi):
class User { constructor(name) { // 構(gòu)造器,相當(dāng)于es5中的構(gòu)造函數(shù) this.name = name // 實(shí)例屬性 } showName(){ // 定義類(lèi)的方法,不能使用function關(guān)鍵字,不能使用逗號(hào)分隔 console.log(this.name) } } var foo = new User("黃繼鵬") foo.showName();//黃繼鵬(1)constructor
es6中class類(lèi)專(zhuān)用的構(gòu)造器,相當(dāng)于之前定義的構(gòu)造函數(shù),每個(gè)類(lèi)都必須有constructor,如果沒(méi)有則自動(dòng)添加一個(gè)空的constructor構(gòu)造器。
創(chuàng)建實(shí)例的時(shí)候自動(dòng)執(zhí)行constructor函數(shù)
constructor中的this指向?qū)嵗⑶夷J(rèn)返回this(實(shí)例)
(2)class類(lèi)的prototype其實(shí)class的基本類(lèi)型就是函數(shù)(typeof User = "function"),既然是函數(shù),那么就會(huì)有prototype屬性。
類(lèi)的所有方法都是定義在prototype上
class User { constructor() { // ... } toString() { // ... } toValue() { // ... } } User.toValue() // err User.toValue is not a function User.prototype.toValue() // 可以調(diào)用toValue方法 // 等同于 User.prototype = { constructor() {}, toString() {}, toValue() {}, };(3)類(lèi)的實(shí)例
類(lèi)的實(shí)例只能通過(guò)new來(lái)創(chuàng)建
除了靜態(tài)方法,定義在類(lèi)上的所有的方法都會(huì)被實(shí)例繼承
除非定義在類(lèi)的this對(duì)象上才是實(shí)例屬性,否則都是定義在類(lèi)的原型(prototype)上
//定義類(lèi) class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return "(" + this.x + ", " + this.y + ")"; } } var point = new Point(2, 3); point.toString() // (2, 3) point.hasOwnProperty("x") // true point.hasOwnProperty("y") // true point.hasOwnProperty("toString") // false point.proto.hasOwnProperty("toString") // true(4)靜態(tài)方法
如果在類(lèi)中定義一個(gè)方法的前面加上static關(guān)鍵字,就表示定義一個(gè)靜態(tài)方法,靜態(tài)方法不會(huì)被實(shí)例繼承,但會(huì)被子類(lèi)繼承,所以不能通過(guò)實(shí)例使用靜態(tài)方法,而是通過(guò)類(lèi)直接調(diào)用
class User { constructor(name){ this.name = name } static show(){ console.log("123") } } class VipUser extends User{} VipUser.show() // 123 User.show() // 123 var foo = new User("foo") foo.show() // foo.show is not a function(5)靜態(tài)屬性
class的靜態(tài)屬性指的是 Class 本身的屬性,目前只能通過(guò)Class.propName定義靜態(tài)屬性
靜態(tài)屬性可以被子類(lèi)繼承,不會(huì)被實(shí)例繼承
class User{} User.name = "foo" // 為class定義一個(gè)靜態(tài)屬性 class VipUser extends User{} console.log(VipUser.name) // foo var foo = new User() console.log(foo.name) // undefined(6)私有屬性和私有方法
es6是不支持私有屬性和私有方法,但是日常需求可能會(huì)用到私有屬性和私有方法,所以目前有一些提案,不過(guò)只是提案,尚未支持。
類(lèi)的繼承
ES5寫(xiě)法
function User(name,pass){ this.name=name; this.pass=pass; } User.prototype.showName=function(){ console.log(this.name); }; /** * [showPass 獲取用戶(hù)密碼] * @return {[type]} [返回用戶(hù)密碼] */ User.prototype.showPass=function(){ console.log(this.pass); }; //繼承user類(lèi) function aUser(name, pass, type) { User.call(this, name, pass); this.type = type; }; aUser.prototype.showType = function() { console.log(this.type); }; var ul=new User("黃繼鵬","abc"); ul.showName()//黃繼鵬 var ull=new aUser("繼小鵬","ccc","男"); ul.showName();//繼小鵬 ull.showType();//男 //aUser繼承類(lèi)User類(lèi),并且有自己的方法
class通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承:
class User { constructor(name){ this.name = name } show(){...} } class VipUser extends User{ constructor(vipName){ // 子類(lèi)的構(gòu)造器 super(vipName) // 調(diào)用父類(lèi)的constructor。相當(dāng)于User.prototype.constructor.call(this,vipName) } showVip(){...} } var v = new VipUser("foo") // 創(chuàng)建實(shí)例 v instanceof VipUser // v是子類(lèi)VipUser的實(shí)例 v instanceof User // v還是父類(lèi)User的實(shí)例(1)super
super可以當(dāng)做函數(shù)使用,也可以當(dāng)做對(duì)象使用。
當(dāng)做函數(shù)使用
super作為函數(shù)調(diào)用時(shí),代表父類(lèi)的構(gòu)造函數(shù),就是在子類(lèi)的構(gòu)造器中執(zhí)行父類(lèi)的constructor函數(shù)以獲取父類(lèi)的this對(duì)象,因?yàn)樽宇?lèi)沒(méi)有自己的this對(duì)象,所以ES6規(guī)定子類(lèi)必須在constructor中執(zhí)行一次super函數(shù)。super()函數(shù)只能在子類(lèi)的constructor中執(zhí)行,不能在其他地方執(zhí)行。
雖然super代表父類(lèi)的構(gòu)造器,但是super()在執(zhí)行時(shí)內(nèi)部的this指向子類(lèi),所以super()就相當(dāng)于User.prototype.constructor.call(this)。
當(dāng)做對(duì)象使用
super可以作為對(duì)象調(diào)用父類(lèi)的屬性和方法,在子類(lèi)的普通方法中,指向父類(lèi)的原型對(duì)象(即User.prototype);在子類(lèi)的靜態(tài)方法中,指向父類(lèi)。
class User { constructor(){ this.x = "hello" } show() { return 2; } } class VipUser extends User { constructor() { super(); console.log(super.show()); // 2 此時(shí)super指向User.prototype,相當(dāng)于User.prototype.show() console.log(super.x) // undefined 無(wú)法訪(fǎng)問(wèn)實(shí)例屬性 } } let vip = new VipUser(); console.log(vip.x);//hello
由于super對(duì)象在普通函數(shù)中使用super指向User.prototype,所以super只能訪(fǎng)問(wèn)父類(lèi)的原型上的方法,沒(méi)法訪(fǎng)問(wèn)父類(lèi)的實(shí)例屬性和實(shí)例方法。
ES6規(guī)定如果在子類(lèi)中使用super對(duì)象調(diào)用父類(lèi)的方法時(shí),方法內(nèi)部的this指向子類(lèi)
class User { constructor() { this.x = 1 } show() { return this.x; } } class VipUser extends User { constructor() { super(); this.x = 2 console.log(super.show()) // 2 此時(shí)show()方法內(nèi)部的this指向子類(lèi),所以輸出2,而不是1 } } let vip = new VipUser();
上述代碼中雖然super.show()調(diào)用的是User.prototype.show(),但是由于通過(guò)super對(duì)象調(diào)用父類(lèi)方法時(shí),方法內(nèi)部的this指向子類(lèi),所以super.show()相當(dāng)于 super.show().call(this),也就是User.prototype.show().call(this)
在子類(lèi)的靜態(tài)方法中super對(duì)象指向父類(lèi),而不是父類(lèi)的原型(User.prototype)。
class User { constructor() { this.x = 1 } static fn() { console.log("父類(lèi)靜態(tài)方法") } } class VipUser extends User { constructor() { super(); this.x = 2 } static childFn() { super.fn() // 相當(dāng)于User.fn() } } VipUser.childFn()(2)類(lèi)的prototype和proto屬性
在es5中每一個(gè)對(duì)象都有proto屬性,指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性。Class 作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有prototype屬性和proto屬性,因此同時(shí)存在兩條繼承鏈。
子類(lèi)的proto屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類(lèi)。
子類(lèi)prototype屬性的proto屬性,表示方法的繼承,總是指向父類(lèi)的prototype屬性。
class User { } class VipUser extends User { } VipUser.proto === User // true VipUser.prototype.proto === User.prototype // true(3)實(shí)例的proto屬性
子類(lèi)實(shí)例的proto屬性指向子類(lèi)的原型(子類(lèi)的prototype),子類(lèi)實(shí)例的proto屬性的proto屬性指向父類(lèi)的原型(父類(lèi)的prototype)
class User { } class VipUser extends User { } var vip = new VipUser() console.log(vip.proto === VipUser.prototype) // true console.log(vip.proto.proto === User.prototype) // true面向?qū)ο?應(yīng)用
面向?qū)ο髴?yīng)用---react
react介紹:
組件化
在react里一個(gè)組件就是一個(gè)class,
依賴(lài)于JSX
jsx==babel==browser.js
ReactDOM.render(
123,
oDiv
);
這種語(yǔ)法為什么會(huì)支持呢?
這個(gè)就是jsx和普通js最大的差別。
你可以認(rèn)為jsx是普通js的擴(kuò)展版本
既然是擴(kuò)展版本,那肯定會(huì)多出一些功能來(lái)。
如果不寫(xiě)引號(hào),不是字符串同時(shí)長(zhǎng)得像html,他就是可以要?jiǎng)?chuàng)建一個(gè)標(biāo)簽
切換搭配重點(diǎn)
react是一個(gè)基于組件
組件與class形式存在
我想寫(xiě)一個(gè)組件,作為一個(gè)組件是不是應(yīng)該有一些基本的功能,比如我能被渲染,我有一些狀態(tài),我有生命周期,換句話(huà)說(shuō)我現(xiàn)在不是從零開(kāi)始寫(xiě)一個(gè)class,我需要很多基礎(chǔ)的類(lèi)的集成。
class Test extends React.Component{ }
類(lèi)繼承最大的意義在于一切不用從零開(kāi)始
一個(gè)類(lèi)需要有構(gòu)造函數(shù)constructor.
作為繼承類(lèi),在構(gòu)造函數(shù)中需要繼承父級(jí)的屬性
組件套組件方法例子
Promise
Promise的中文含義是承諾
了解Promise之前。先來(lái)了解下同步異步
異步:操作之間沒(méi)啥管系,同時(shí)進(jìn)行多個(gè)操作
同步:同時(shí)只能做一件事
同步異步的優(yōu)缺點(diǎn)
異步:代碼更復(fù)雜
同步:代碼簡(jiǎn)單
一個(gè)頁(yè)面可能會(huì)有多個(gè)請(qǐng)求
比如淘寶網(wǎng)頁(yè),banner區(qū)域,側(cè)邊欄,導(dǎo)航欄,右側(cè)欄,信息商品等
都是由鍍鉻接口異步請(qǐng)求組成
這就回造成代碼邏輯復(fù)雜
按照以往前端ajax請(qǐng)求寫(xiě)法。一個(gè)請(qǐng)求成功后繼續(xù)請(qǐng)求嵌套。邏輯會(huì)變得異常費(fèi)勁
異步
$.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/1", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功") }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, })
同步
let banner_data=ajax_async("/banner"); let banner_data1=ajax_async("/banner1"); let banner_data2=ajax_async("/banner2"); let banner_data3=ajax_async("/banner3"); let banner_data4=ajax_async("/banner4");
你會(huì)發(fā)現(xiàn)異步處理性能好,用戶(hù)體驗(yàn)好,但實(shí)際代碼復(fù)雜
要是同步方式頁(yè)面用戶(hù)體驗(yàn)不好
這個(gè)時(shí)候幻想一下,我能不能像同步方式來(lái)寫(xiě)代碼。也像異步一樣請(qǐng)求數(shù)據(jù)。
Promise就能做到這個(gè)工作
Promise--消除異步操作
用同步書(shū)寫(xiě)方式,來(lái)書(shū)寫(xiě)異步方法
Promise如何使用
需要使用promise的時(shí)候,你需要new一個(gè)promise對(duì)象。
這個(gè)對(duì)象接收一個(gè)參數(shù),是一個(gè)函數(shù)。
將異步的代碼寫(xiě)在函數(shù)里
這個(gè)函數(shù)兩個(gè)參數(shù)
resolve決心
reject拒絕
//封裝Promise ajax let p=new Promise(function(resolve,reject){ //異步代碼塊 //resolve--成功了 //reject--失敗了 $.ajax({ type: "post", dataType:"json", url: "/api/banner", success:function(result){ resolve(result); }, error:function(error){ reject(error); }, }) }); //使用Promise ajax封裝 //當(dāng)Promise調(diào)用有結(jié)果了就會(huì)調(diào)用then //then有兩個(gè)參數(shù),都是函數(shù),第一個(gè)是resolve,第二個(gè)是reject p.then((result)=>{ console.log(result); },(error)=>{ console.log(error); })
function createPromise(url){ return new Promise(function(resolve,reject){ //異步代碼塊 //resolve--成功了 //reject--失敗了 $.ajax({ type: "post", dataType:"json", url, success:function(result){ resolve(result); }, error:function(error){ reject(error); }, }) }); } createPromise("./aa") .then((res)=>{ console.log(res) },(err)=>{ console.log(err) })
function createPromise(url){ return new Promise(function(resolve,reject){ //異步代碼塊 //resolve--成功了 //reject--失敗了 $.ajax({ type: "post", dataType:"json", url, success:function(result){ resolve(result); }, error:function(error){ reject(error); }, }) }); } Promise.all([ createPromise("./aa"), createPromise("./bb") ]) .then((res)=>{ let [arr1,arr2]=res },(err)=>{ console.log(err) })generator-認(rèn)識(shí)生成器函數(shù)
generator的作用
generator-生成器
生成器是程序里面的一個(gè)概念,可以依靠它生成一堆東西
Generator可以理解為生成器,和普通函數(shù)沒(méi)多大區(qū)別,普通函數(shù)是只要開(kāi)始執(zhí)行,就一直執(zhí)行到底,而Generator函數(shù)是中間可以停,搭配使用next函數(shù)繼續(xù)執(zhí)行。
生動(dòng)的比喻
普通函數(shù)好比坐飛機(jī),飛機(jī)起飛,不到目的地中途是不會(huì)降落的
Generator好比于出租車(chē)。可以隨叫隨停。停了再走,走了再停
(1)定義一個(gè)Generator函數(shù)function * fn(){ alert("a") yield alert("b") } var f = fn() f.next() // a f.next() // b
直接調(diào)用Generator函數(shù),是什么都不執(zhí)行的,調(diào)用第一個(gè)next()才開(kāi)始執(zhí)行,一直執(zhí)行到第一個(gè)yield停止,第二次調(diào)用next(),從第一個(gè)yield執(zhí)行到第二個(gè)yield停止,依次類(lèi)推
現(xiàn)在疑惑,在真實(shí)場(chǎng)景中,我為什么要讓一個(gè)函數(shù)停呢?
剛才舉個(gè)了出租車(chē)的例子,說(shuō)白了,你為什么要讓出租車(chē)司機(jī)停車(chē),肯定是你有事情,你要去忙,或者要求拿什么東西,或者見(jiàn)什么朋友。
等你事情辦完了,還再回來(lái)。
所以Generator特別適合一個(gè)場(chǎng)景。
比如說(shuō)你要請(qǐng)求數(shù)據(jù)。請(qǐng)求數(shù)據(jù)不是瞬間就能回來(lái)的,這個(gè)時(shí)候就需要暫停,來(lái)等他結(jié)果過(guò)來(lái)。再繼續(xù)執(zhí)行下面的操作。
/** * 普通函數(shù)在執(zhí)行過(guò)程中需要請(qǐng)求得到結(jié)果再執(zhí)行對(duì)應(yīng)代碼,就會(huì)出現(xiàn)代碼嵌套再嵌套 */ function 函數(shù)(){ 代碼... ajax({ 代碼... }) } /** * Generator函數(shù)可以讓代碼在那一步暫時(shí)暫停 拿到數(shù)據(jù)后再繼續(xù)往下走 */ function *函數(shù)(){ 代碼... yiels ajax(xxx) 代碼... }
Generator是怎么做到走走停停的?
其實(shí)本質(zhì)是用Generator函數(shù)生成了一堆小函數(shù)
比方說(shuō)fn函數(shù)
function * fn(){ alert("a") yield alert("b") } var f = fn() f.next() // a f.next() // b
其實(shí)他在背后生成了兩個(gè)小函數(shù)
function fn_1(){ alert("a") } function fn_2(){ alert("b") }
當(dāng)然這個(gè)過(guò)程我們是看不見(jiàn)的
相當(dāng)于把一個(gè)大函數(shù)切分成了兩個(gè)小函數(shù)
第一次next的時(shí)候他走的是fn_1
第二次next的時(shí)候走的是fn_2
generator-yieldyield和next
yield代表暫時(shí)暫停執(zhí)行,next代表繼續(xù)執(zhí)行。
yield和next可以傳參數(shù),也可以有返回值
yield可以傳參
function *show(){ console.log("a") let a=yield; console.log("b") console.log(a) } let gen=show(); gen.next(12) gen.next(5) //a //b //5
第一次執(zhí)行next的時(shí)候執(zhí)行黃色框代碼
第二次執(zhí)行紅色框的代碼
傳參的時(shí)候通過(guò)yield來(lái)傳參的時(shí)候,第一個(gè)next是無(wú)效的,
如果想給第一個(gè)過(guò)程傳參需要使用傳統(tǒng)方法,在使用函數(shù)時(shí)傳參
function *show(num1,num2){ console.log(`${num1},${num2}`) console.log("a") let a=yield; console.log("b") console.log(a) } let gen=show(11,12); gen.next(12);//沒(méi)法給yield傳參 gen.next(5) //11,12 //a //b //5
yield返回
function *show(){ console.log("a") let a=yield 12; console.log("b") } let gen=show(11,12); let res1=gen.next(); console.log(res1) let res2=gen.next() console.log(res2) //a //{value: 12, done: false} //b //{value: undefined, done: true}
value是yield 返回的參數(shù)
done代碼函數(shù)是否走完
為什么第二次執(zhí)行完value是空
因?yàn)榈诙蝞ext是執(zhí)行的最后一道程序,最后一道程序就沒(méi)有yield 了,如果想返回東西需要使用return
function *show(){ console.log("a") let a=yield 12; console.log("b") return 111; } let gen=show(11,12); let res1=gen.next(); console.log(res1) let res2=gen.next() console.log(res2) //a //{value: 12, done: false} //b //{value: 111, done: true}
yield 到底是個(gè)啥
generator-實(shí)例:runner這種Generator函數(shù)適用多個(gè)異步請(qǐng)求之間有邏輯分析的情況,比如有一個(gè)需求,先請(qǐng)求用戶(hù)數(shù)據(jù),根據(jù)用戶(hù)數(shù)據(jù)的類(lèi)型判斷用戶(hù)是普通用戶(hù)還是VIP用戶(hù),然后再根據(jù)判斷結(jié)果請(qǐng)求普通商品數(shù)據(jù)或者VIP商品數(shù)據(jù)
// 借助runner腳本,runner腳本規(guī)定Generator函數(shù)執(zhí)行完一個(gè)next之后自動(dòng)執(zhí)行下一個(gè)next runner(function() * (){ let userData = yield $.ajax(...) // 請(qǐng)求用戶(hù)數(shù)據(jù) if(userData.type === "vip") { let goods = yield $.ajax(...) // 請(qǐng)求vip商品數(shù)據(jù) } else { let goods = yield $.ajax(...) // 請(qǐng)求普通商品數(shù)據(jù) } })
第一次yield ajax其實(shí)是Promise對(duì)象,將Promise對(duì)象yield 出去。
yield 給了runner對(duì)象
將數(shù)據(jù)請(qǐng)求完成給data1
這個(gè)函數(shù)暫停了
使用Generator函數(shù)使得代碼看起來(lái)更像同步代碼,其實(shí)使用Promise同樣可以實(shí)現(xiàn)這種效果,只不過(guò)得需要在then()函數(shù)中嵌套請(qǐng)求。
異步請(qǐng)求的幾種方式
回調(diào)寫(xiě)法
$.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/1", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功"); $.ajax({ type: "post", url: "/api/banner", success:function(result){ console.log("成功") }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, }) }, error:function(error){ console.log("失敗") }, })
Promise寫(xiě)法
function createPromise(url){ return new Promise(function(resolve,reject){ //異步代碼塊 //resolve--成功了 //reject--失敗了 $.ajax({ type: "post", dataType:"json", url, success:function(result){ resolve(result); }, error:function(error){ reject(error); }, }) }); } Promise.all([ createPromise("./aa"), createPromise("./bb") ]) .then((res)=>{ let [arr1,arr2]=res },(err)=>{ console.log(err) })
Generator寫(xiě)法
runner(function() * (){ let userData = yield $.ajax(...) // 請(qǐng)求用戶(hù)數(shù)據(jù) if(userData.type === "vip") { let goods = yield $.ajax(...) // 請(qǐng)求vip商品數(shù)據(jù) } else { let goods = yield $.ajax(...) // 請(qǐng)求普通商品數(shù)據(jù) } })
Promise和Generator相比,Generator并沒(méi)有特別的省事
Promise也有它不適用的地方。我如果是寫(xiě)死要請(qǐng)求接口。那么Promise和Generator確實(shí)沒(méi)太大區(qū)別,
Generator他的優(yōu)點(diǎn)在于適合參雜一些邏輯
比方說(shuō)在請(qǐng)求一個(gè)接口拿到用戶(hù)信息,根據(jù)信息判斷他該去請(qǐng)求哪些不同的接口
感覺(jué)比普通嵌套還麻煩
帶邏輯-Generator
// 借助runner腳本,runner腳本規(guī)定Generator函數(shù)執(zhí)行完一個(gè)next之后自動(dòng)執(zhí)行下一個(gè)next runner(function() * (){ let userData = yield $.ajax(...) // 請(qǐng)求用戶(hù)數(shù)據(jù) if(userData.type === "vip") { let goods = yield $.ajax(...) // 請(qǐng)求vip商品數(shù)據(jù) } else { let goods = yield $.ajax(...) // 請(qǐng)求普通商品數(shù)據(jù) } })
Promise適合一次請(qǐng)求一堆場(chǎng)景
Generator適合邏輯性請(qǐng)求處理
KOA是nodejs的框架
async awaitasync其實(shí)就是對(duì)Generator的封裝,只不過(guò)async可以自動(dòng)執(zhí)行next()。
async function read () { let data1= await new Promise(resolve => { resolve("100") }) let data2 = await 200 return 300 }async 返回值
async默認(rèn)返回一個(gè)Promise,如果return不是一個(gè)Promise對(duì)象,就會(huì)被轉(zhuǎn)為立即resolve的Promise,可以在then函數(shù)中獲取返回值。
async必須等到里面所有的await執(zhí)行完,async才開(kāi)始return,返回的Promise狀態(tài)才改變。除非遇到return和錯(cuò)誤。
async function fn () { await 100 await 200 return 300 } fn().then(res => { console.log9(res) // 300 })await
await也是默認(rèn)返回Promise對(duì)象,如果await后面不是一個(gè)Promise對(duì)象,就會(huì)轉(zhuǎn)為立即resolve的Promise
如果一個(gè)await后面的Promise如果為reject,那么整個(gè)async都會(huì)中斷執(zhí)行,后面的awiat都不會(huì)執(zhí)行,并且拋出錯(cuò)誤,可以在async的catch中捕獲錯(cuò)誤
async function f() { await Promise.reject("error"); await Promise.resolve("hello world"); // 不會(huì)執(zhí)行 } f().then(res =>{ }).catch(err=>{ console.log(err) // error })
如果希望一個(gè)await失敗,后面的繼續(xù)執(zhí)行,可以使用try...catch或者在await后面的Promise跟一個(gè)catch方法:
// try...catch async function f() { try { await Promise.reject("出錯(cuò)了"); } catch(e) { } return await Promise.resolve("hello world"); } f() .then(v => console.log(v)) // hello world // catch async function f() { await Promise.reject("出錯(cuò)了") .catch(e => console.log(e)); // 出錯(cuò)了 return await Promise.resolve("hello world"); } f() .then(v => console.log(v)) // hello world
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102509.html
摘要:所以,當(dāng)函數(shù)傳參為時(shí),短路操作符會(huì)給定默認(rèn)值。對(duì)于來(lái)說(shuō),無(wú)論是否在嚴(yán)格模式下,更改參數(shù)值的行為都不會(huì)同步更改對(duì)象。且箭頭函數(shù)中的值無(wú)法改變而非箭頭函數(shù)也正因?yàn)槿绱耍^函數(shù)無(wú)法作為構(gòu)造函數(shù),因?yàn)橹禑o(wú)法綁定至構(gòu)造函數(shù)的實(shí)例。 如同我們所看到的,ES6 中引入來(lái)箭頭函數(shù),相比 ES5 來(lái)講是最為直觀而明顯的特性。 在 ES6 之前,聲明一個(gè)函數(shù): function add(a, b) { ...
摘要:在之前,中沒(méi)有常量聲明方式,有的僅僅是一種命名上的約定。這樣就可以最大程度上規(guī)避變量的意外變化來(lái)使程序發(fā)生異常的可能性。為了避免作用域的污染,在中需要使用一個(gè)立即執(zhí)行函數(shù)來(lái)確保變量的作用域范圍。 在 ES6 之前,JS 中沒(méi)有常量聲明方式,有的僅僅是一種命名上的約定。 var PI = 3.14; PI = 4; console.log(PI); // 4 我們用大寫(xiě)變量名來(lái)標(biāo)識(shí)這是一...
摘要:在年正式發(fā)布了,簡(jiǎn)稱(chēng),又稱(chēng)為。再次簡(jiǎn)寫(xiě)循環(huán)迭代數(shù)組每個(gè)元素都執(zhí)行一次回調(diào)函數(shù)。方法用于調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)。注意對(duì)于空數(shù)組是不會(huì)執(zhí)行回調(diào)函數(shù)的。 轉(zhuǎn)載請(qǐng)注明出處 原文連接 http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d es6 是什么 首先弄明白ECMA和js的關(guān)系。ECMA是標(biāo)準(zhǔn),Jav...
摘要:以下,請(qǐng)求兩個(gè),當(dāng)兩個(gè)異步請(qǐng)求返還結(jié)果后,再請(qǐng)求第三個(gè)此處為調(diào)用后的結(jié)果的數(shù)組對(duì)于來(lái)說(shuō),只要參數(shù)數(shù)組有一個(gè)元素變?yōu)闆Q定態(tài),便返回新的。 showImg(https://segmentfault.com/img/remote/1460000015444020); Promise 札記 研究 Promise 的動(dòng)機(jī)大體有以下幾點(diǎn): 對(duì)其 api 的不熟悉以及對(duì)實(shí)現(xiàn)機(jī)制的好奇; 很多庫(kù)(比...
閱讀 897·2023-04-26 01:37
閱讀 3370·2021-09-02 15:40
閱讀 960·2021-09-01 10:29
閱讀 2895·2019-08-29 17:05
閱讀 3425·2019-08-28 18:02
閱讀 1183·2019-08-28 18:00
閱讀 1490·2019-08-26 11:00
閱讀 2610·2019-08-26 10:27