深入理解 ES6

let && const

let與var的聲明用法相同,但是多了一個臨時死區(Temporal Distonrtion Zone)的概念。

console.log(a)// -> undefinedvara =1console.log(b)// -> Uncaught ReferenceError: b is not definedletb =1

可以發現在聲明前使用let聲明的變量會導致報錯,這解決了 JS 很多奇怪的問題。并且使用let會生成一個塊級作用域,作用域外不能訪問該變量。

{leta =1;varb =1;}console.log(b);// -> 1console.log(a);//? -> Uncaught ReferenceError: b is not defined

在 JS 中,聲明變量都會提升,不論用什么關鍵字聲明。當使用let時變量也會被提升至塊級作用域的頂部,但是只提升聲明,不提升初始化。并且會產生臨時死區,該區域會存放變量,直到執行過聲明語句后,方可使用該變量。

在循環中let會與前面有些不同,每次迭代都會產生一個新的變量,并用之前的值初始化,如何理解這句話呢,請看以下代碼。

for(leti =0; i <10; i++) {console.log(i)// -> 輸入 0 - 9}// 上面的循環代碼可以這樣看{// 形成塊級作用域leti =0{letii = iconsole.log(ii)? ? }? ? i++? ? {letii = iconsole.log(ii)? ? }? ? i++? ? {letii = iconsole.log(ii)? ? }? ? ...}

const與let基本類似,只是用const聲明必須賦值,并且不得修改綁定,什么意思呢,請看代碼。

consta =1;a =2// -> Uncaught TypeError: Assignment to constant variable// butconstb = {a:1};b.a =2// 起效

當然了,有辦法讓這個不能改變

constb =Object.freeze({a:1})b.a =2// 沒有報錯,但是 b.a 沒有被改變

但是Object.freeze只能在這里有效,對于數組這些可以看看這個提案

這兩個新的聲明方式在全局作用域下不會自動加上window

字符串相關

部分新增的字符串函數

letstring ='startend'string.includes('a')// -> true 是否包含string.endsWith('end')// -> true 是否由 end 結尾string.startsWith('start')// -> true 是否由 start 開頭

模板字面量

很棒的新功能,解決了之前很多麻煩的寫法。

// 語法就是 `` 代替之前的引號,在 `` 中使用引號不需要轉義lets =`it's string`

多行字符串

// 這樣在語法中就可以換行了lets =`start \

end`// 注意在模板字面量中的任何空白符都是起效的lets =`start \

? ? end`// ->? start? ? end

占位符和標簽模板

lets ='string'letmessage =`start${s}`// -> startstring// ${} 就是占位符語法,可以更簡便的實現字符串插入// 定義一個 tag 函數,然后直接在 `` 前使用就可以letm = tag`s${s}e${message}`// strings 是一個數組,value 是模板字面量中所有的占位符的值functiontag(strings, ...value){// -> ['s', 'e', '']console.log(strings)// -> ['string', 'startstring']console.log(value)}// 上面的 ...value 也是 ES6新出的擴展語句,在這里代表不定參數的寫法,用于替換 arguments// 不定參數使用上也是有限制的,必須放在所有參數的末尾,并且在每個函數中只能聲明一次// 擴展語句和 arguments 區別就是代表了 strings 參數后面的所有參數// 除了上面的寫法,還可以用于展開可以迭代(有Symbol.iterator屬性)的對象letarray = [1,2,3]console.log(...array)// 該語法可以解決之前很多地方只能傳入單個參數,只能使用 apply 解決的問題Array.prototype.unshift.apply([4,5], array)// -> [1, 2, 3, 4, 5]// 現在可以直接這樣寫[4,5].unshift(...array)// 展開運算不受不定參數的條件限制,可以一起用

函數

默認參數

ES6 允許給函數增加默認參數

functionfn(a =1, b =2){}// 默認值也可以通過調用函數獲得,注意必須調用函數functionfn1(a =1, b = fn()){}

新增函數內部方法

在 JS 中,函數有多種用法,可以直接調用,也可以通過new構造函數。

在 ES6中,函數內部新增了 [[Call]] 和 [[Construct]] 兩個方法。后者會在使用new構造函數時執行,其他情況會執行前者方法。

當一個函數必須使用new構造時,你可以使用這個新屬性new.target判斷

// new.target 只能在函數中使用functionFn(){if(typeofnew.target ==='underfined') {throw....... }}

箭頭函數

這個特性真的很棒,先介紹下他的幾種語法

// 最簡單的寫法,只有一個參數,單行表達式value => value// 多個參數需要使用小括號包裹(v1, v2) => v2 + v1// 沒有參數需要使用小括號包裹() =>"balabala"http:// 多行表達式需要大括號包裹(v1, v2) => {returnv1 + v2}// 返回一個對象,需要用小括號包裹() => ({a:1})// 立即執行函數,注意普通的立即執行函數的小括號包裹在最外面,箭頭函數不需要((value) =>value)("balabala")

箭頭函數和普通函數區別還是蠻大的,說幾個常用的

沒有this,不能改變this綁定

不能通過new調用,當然也沒有原型

沒有arguments對象,不能有相同命名參數

箭頭函數雖然沒有this,但是還是可以在內部使用this的

this的綁定取決于定義函數時的上下文環境

一旦函數調用,任何改變this的方法都無效

// let 有個細節letx =11111leta = {x:1,? ? init() {// 箭頭函數的 this 取決于 init,所以可以打印出 1document.addEventListener('click', () =>console.log(this.x))? ? },allowInit:()=>{// allowInit 直接是個箭頭函數,所以這時的 this 變成了 window// 但是并不會打印出 11111,忘了 let 的一個細節的可以回到上面看看console.log(this.x))? ? }? ? otherInit() {// 普通函數的 this 取決于調用函數的位置,this 指向 document// 如果想打印出 x,可以使用 binddocument.addEventListener('click',function(){console.log(this.x)? ? ? ? })? ? }}a.init()// -> 1a.allowInit()// -> undefineda.otherInit()// -> undefined

對象相關

leta =1// 當 key 和 value 名字相同時可以簡寫letb = { a }// 對象中的方法也可以簡寫leta = {? ? init() {}}// 對象屬性名也可以計算 letname ='name'b[name +'1'] =2// === b['name1'] = 2

ES6 也新增了幾個對象方法

Object.is(NaN,NaN)// ->true// 結果基本于 === 相似,除了 NaN 和 +0 -0Object.is(+0,-0)// -> falseleto = {a:1}leta =Object.assign({}, o)// -> {a: 1}// 第一個參數為目標參數,后面的參數是不定的,參數屬性名如果有重復,后面的會覆蓋之前的

原型相關

ES6 之前改變對象原型很麻煩

letobj = {a:1}letobj1 = {a:2}// 已 obj 為原型leta =Object.create(obj)// 改變 a 的原型為 obj1Object.setPrototypeOf(a, obj1)// a.a === 2

訪問原型

Object.getPrototypeOf(a)// 訪問原型// ES6 中可以直接通過 super 代表原型leta = {? ? init() {return'Hello'}}letb = {? ? init() {// 不能在 super 之前訪問 thisreturnsuper.init() +'World'}}Object.setPrototypeOf(b, a)b.init()// -> 'HelloWorld'

但是 super 不是每個函數都可以使用的,只有在函數的簡寫語法中方可使用。因為在 ES6中新增了一個函數內部屬性 [[HomeObject]],這個屬性決定了是否可以訪問到super。首先在該屬性上調用Object.getPrototypeOf(綁定的對象),然后找到原型中的同名函數,在設置this綁定并且調用函數,其實就是一個新增的語法糖。

解構賦值

該特性可以用于對象,數組和傳參。

letobj = {a:1,b:2}// 對象解構使用 {},數組解構使用 [],因為這里是對象解構,c 不是 obj 的屬性,所以 underfined// 數組解構中,如果需要解構的變量大于數組索引,多出來的變量也是 undefined// 解構必須賦值,否則報錯。不能 let {a, b, c};// 賦值不能為 null 或者 undefined,會報錯let{a, b, c} = obj// 等于 let a = obj.a,可以看做之前介紹的對象屬性簡寫console.log(a, b, c)// -> 1, 2, underfined// 如果已經聲明了變量并且想使用解構,必須最外面是小括號({a, b} = obj)// 如果不想使用 obj 中的對象名,又想使用解構賦值let{x: a} = obj// 如果想使用默認值let{a =2, c=3} = obj// -> 1, 3// 因為 a 是 obj 中的對象,所以默認值被覆蓋// 解構也可以嵌套letobj = {data: {code:1},message: [1,2]}// 這個寫法在 json 中很好用// 注意在這個寫法中,data 和 message 都是指代了 obj 的屬性,并沒有被聲明變量let{data: {code},message: [a] } = objconsole.log(code, a)// 數組解構和對象解構基本相似,并且簡單多了letmessage = [1,2,3,4]// 因為數組取值只能索引取,所以想跳過某幾個索引,就用逗號代替// 同樣,數組解構也可以使用默認值和嵌套解構,和對象解構一模一樣就不贅述了let[a, , b] = message// -> 1, 3// 在上面章節介紹了擴展語法,同樣也可以使用在數組解構中// 可以看到 b 變成了一個數組let[a, ...b] = message// -> 1, [2, 3, 4]// 傳參使用解構可以讓要傳的參數更加清晰functionfn(name, {key, value}){console.log(name, key, value)}// 使用,注意:傳參解構必須起碼傳入一個值,否則報錯fn(1, {key:2,value:3})// 因為傳參解構類似以下寫法functionfn(name, {key, value}){let{key, value} =null// 這個上面講過不能這樣寫}

Symbol

ES6 新出的第六個原始類型。多用于避免代碼沖突,作為一個私有屬性使用,不會被屬性遍歷出來。可以使用Object.getOwnPropertySymbols()檢索 Symbol 屬性。

創建和使用

// 創建leta =Symbol()// 更推薦這種寫法,可以更加明確這個Symbol的用途// 并且有函數可以通過這個字符串取到相應的Symbolletb =Symbol('is b')// 使用,一般作為可計算屬性使用leta = {}letb =Symbol('is b') a[b] =1// 可以在全局注冊表中共享同一個 Symbol,但不推薦使用// 不存在 is a 會自動創建leta =Symbol.for('is a')

暴露內部操作

Symbol 中預定義了一些 well-know Symbol,這些 Symbol 定義了一些語言的內部實現

Symbol.hasinstance,用于執行instanceof時檢測對象的繼承信息

Symbol.isConcatSpreadable,布爾值,用于判斷當使用concat函數時是否將數組展開

Symbol.iterator,迭代器,后面會講到

Symbol.match,Symbol.replace,Symbol.search,Symbol.split,字符串相關方法的對應內部實現

Symbol.toPrimitive,返回對象原始值

Symbol.toStringTag,調用toString

Set 和 Map

Set

Set 是新增的無重復的有序集合,多用于集合去重或者判斷集合中是否含有某個元素。

// 創建letset =newSet()// 添加元素set.add(1)set.add('1')// 重復的元素不會被添加set.add(1)// 判斷是否包含元素set.has(1)// -> true// 判斷長度set.size()// -> 2// 刪除某個元素set.delete()// 移除所有元素set.clear()

Map

Map 是新增的有序鍵值對列表,鍵值可以是任何類型。

// 創建letmap =newMap()// 設置鍵值對map.set('year',"2017")map.set({},'obj')// 取值map.get('year')// -> '2017'// 判斷是否有該鍵值map.has('year')// -> true// 獲得長度map.size()// -> 2// 刪除某個鍵值map.delete('year')// 移除所有鍵值map.clear()

迭代器和 Generator 函數

迭代器

顧名思義,用來迭代的。之前介紹過Symbol.iterator,可以迭代的對象都有這個屬性,包括數組,Set,Map,字符串和 NodeList。ES6新增的for-of就用到了迭代器的功能,但是默認只有上面這些對象能使用。

leta = [1,2]for(letvalueofa) {console.log(value)// -> 1, 2}// 上面的代碼其實就是調用了數組的默認迭代器letiterator = a[Symbol.iterator]()// 當調用 next 時會輸出這次迭代的 value 和是否迭代完成console.log(iterator.next())// {value: 1, done: false}console.log(iterator.next())// {value: 2, done: false}// 已經沒元素可以迭代了console.log(iterator.next())// {value: undefined, done: true}// 數組的默認迭代器只會輸出 value,如果想同時輸出索引的話// 這里可以使用新特性數組解構 let [index, value]for(letvalueofa.entries()) {console.log(value)// -> [0, 1]? [1, 2]}

對于自己創建的對象都是不可迭代的,當然我們也可以讓他變成迭代的

leta = {array: [],// 這是一個 Generator 函數,馬上就會講到*[Symbol.iterator]() {for(letiteminthis.array) {yielditem? ? ? ? }? ? }}a.array.push(...[1,2,3])for(letitemofa) {console.log(item)}

Generator 函數

用于異步編程。該函數可以暫停和恢復執行,和同步寫法很像。

// 星號表示這是一個 Generator 函數function*gen(){// 第一次 next 只執行到等號右邊letfirst =yield1// 第二次 next 執行 let first = 和 yield 2letsecond =yield2// 不執行接下來的 next 就卡在上一步了letthrid =yield3}letg = gen()g.next()// -> {value: 1, done: false}g.next()// -> {value: 2, done: false

接下來看下 Generator 函數如何用于異步

functiongetFirstName(){? ? setTimeout(function(){? ? ? ? gen.next('alex')? ? },1000);}functiongetSecondName(){? ? setTimeout(function(){? ? ? ? gen.next('perry')? ? },2000);}function*sayHello(){vara =yieldgetFirstName();varb =yieldgetSecondName();// settimeout 本來是異步的,通過 Generator 函數寫成了同步寫法console.log(a, b);// ->alex perry}vargen = sayHello();gen.next();

JS 中的類不是其他語言中的類,只是個語法糖,寫法如下。

classPerson{// 構造函數constructor() {this.name = name? ? }? ? sayName() {console.log(this.name)? ? }}letp =newPerson('name')p.sayName()// -> 'name'// class 就是以下代碼的語法糖// 對應 constructorfunctionPerson(name){this.name = name}// 對應 sayNamePerson.prototype.sayName =function(){console.log(this.name)}

類聲明相比之前的寫法有以下幾點優點

類聲明和 let 聲明一樣,有臨時死區

類聲明中的代碼全部運行在嚴格模式下

必須使用 new 調用

繼承

在 ES6 之前寫繼承很麻煩,既然有個類,那么必然也可以繼承類了

classPerson{// 構造函數constructor() {this.name = name? ? }? ? sayName() {console.log(this.name)? ? }}// extends 代表繼承自PersonclassStudentextendsPerson{constructor(name, age) {// super 的注意事項之前有說過super(name)// 必須在 super 之后調用 thisthis.age = age? ? }? ? sayName() {// 如果像使用父類的方法就使用這個方法使用// 不像使用的話就不寫 super,會覆蓋掉父類的方法super.sayName(this.name)console.log(this.age)? ? }}

Promise

概念

用于異步編程。

// 你可以使用 new 創建一個 Promise 對象letpromise =newPromise(function(resolve, reject)){}resole()// 代表成功reject()// 代表失敗promise.then(onFulfilled, onRejected)// 當調用 resole 或者 reject ,then 可以監聽到promise.catch()// reject 或者 throw時可以監聽到

Promise 有三個狀態

pending,等待狀態,也就是既不是 resolve 也不是 reject 狀態

fulfilled,resolve 以后進入這個狀態

reject,reject 以后進入這個狀態

一般使用情況

functiondelay(){// 創建一個 promisereturnnewPromise((resolve, reject) =>{// 當調用 promise 時,里面的內容會立即執行console.log('in delay')? ? ? ? setTimeout(()=>{? ? ? ? ? resolve(1)? ? ? ? },1000)? ? });}functionotherDelay(){returnnewPromise((resolve, reject) =>{? ? ? ? setTimeout(()=>{? ? ? ? ? reject(1)? ? ? ? },1000)? ? });}// 這里會先輸出 delay 函數中的 log,然后再輸出 outer,接下來1秒以后輸出3個1delay()// then 可以捕獲 resolve 和 reject.then((value) =>{console.log(value)? ? })console.log('outer')otherDelay()// 捕獲 reject時,如果不需要捕獲 resolve 時可以這樣寫.then(null, (value) => {console.log(value)? ? })// 捕獲 reject 或者 throw 時推薦使用這個寫法,原因后面會說otherDelay()? ? .catch((value) =>{console.log(value);? ? })

以上是最常用的 Promise 寫法,現在介紹 Promise 鏈

delay()// then 會返回一個新的 promise 對象.then((value) =>{// 這樣就可以傳參了returnvalue +1}).then((value) =>{console.log(value)// -> 2// then 里面可以也可以傳入一個函數名,會自動調用// 如果傳入的函數有參數會自動傳入}).then(delay).then((value) =>{console.log(value)// -> 1// 如果在then 中拋出錯誤,只有 catch 才能監聽到,所以推薦使用 catch 監聽錯誤thrownewError('error')? ? }).then((value) =>{console.log(value)// 這個then 不會執行}).catch((error) =>{console.log('catch'+ error)// -> catch Error})

Promise 高級用法

開發中可能會有需求,需要一次上傳幾張圖片,全部上傳成功以后有個提示,這時候就可以用到Promise.all()

functionupdateOne(){returnnewPromise((resolve, reject) =>{? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve('one')? ? ? ? ? ? },1000)? ? });}functionupdateTwo(){returnnewPromise((resolve, reject) =>{? ? ? ? setTimeout(()=>{? ? ? ? ? ? resolve('two')? ? ? ? ? ? },2000)? ? });}// all 函數接收一個可迭代對象,注意這里傳入函數必須調用letpromise =Promise.all([updateOne(), updateTwo()])// 只有當 all 中的異步全部完成了才會調用 thenpromise? ? .then((value) =>{// value 是個函數,順序按照 all 里的迭代對象的順序console.log(value)// -> ["one", "two"]})

如果一個異步任務超時了,你想直接取消,可以通過Promise.race()

// 假設該任務執行時間超過1秒就算超時,應該 cancelfunctiondelay(){returnnewPromise((resolve, reject) =>{? ? ? ? setTimeout(function(){? ? ? ? ? ? resolve('finish')? ? ? ? },1500);? ? });}functioncancel(){returnnewPromise((resolve, reject) =>{? ? ? ? setTimeout(function(){? ? ? ? ? ? resolve('cancel')? ? ? ? },1000);? ? });}// 接收的參數和 all 相同letpromise =Promise.race([delay(), cancel()])// race 中只要有一個任務完成,then 就會被調用,這樣就可以 cancel 掉所有超時任務promise? ? .then((value) =>{console.log(value)// -> cancel})

Proxy

Proxy 可以創建一個代替目標對象的代理,攔截語言內部的操作。

lethandle = {}lettarget = {}// 這樣就創建了target 對象的代理,但是這個代理其實沒有任何用處letp =newProxy(target, handle)

上面的代碼中可以看到傳入了一個handle的對象,只有當這個對象中包含一些代理行為的函數時,這個代理才有用。具有的代理行為函數可以去MDN查看,這里舉例幾個用法。

lethandle = {// 改變 set 的內部操作set(target, key, value) {// 當給 age 屬性賦值小于19時報錯console.log(value)if(key ==='age') {if(value <19) {thrownewError('未成年')? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }lettarget = {}letp =newProxy(target, handle)p.age =1// -> 報錯p.age =19// -> 沒問題

模塊化

ES6 引入了原生的模塊化,這樣就可以拋棄之前的 AMD 或者 CMD 規范了,如果對模塊化還沒什么了解,可以看下我之前的文章明白 JS 模塊化

// example.js 文件下// export 可以導出任何變量,函數或者類exportvarage =14exportfunctionsum(n1, n2){returnn1 + n2}exportclassPerson{constructor(age) {this.age = age? ? }}// 別的 JS 文件中導入// 如果想導入整個模塊并且自己命名,就可以這樣使用// import 后面代表模塊名,from 后面代表要導入的文件地址import*asExamplefrom'./example'console.log(Example.age)// -> 14// 當然你也可以只使用模塊中的一個功能// 這里使用了對象解構的方法拿到需要的功能,注意這里名字必須相同,否則使用會報錯import{ age, sum }from'./example'console.log(age)// -> 14console.log(sum(1,2))// -> 3// 現在我只想導出一個功能,并且外部可以隨便命名該如何做呢?// default 一個文件中只能使用一次exportdefaultvarage =14// MyAge 可以隨便自己喜歡命名importMyAgefrom'./example'console.log(MyAge)// -> 14

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容

  • 第一章:塊級作用域綁定 塊級聲明 1.var聲明及變量提升機制:在函數作用域或者全局作用域中通過關鍵字var聲明的...
    BeADre_wang閱讀 849評論 0 0
  • *node下用express框架,實現一個簡單的mvc *構建工具:gulp / babel / webpack ...
    韓娜愛吃辣_前端程序媛閱讀 1,108評論 0 1
  • 1、新的聲明方式 以前我們在聲明時只有一種方法,就是使用var來進行聲明,ES6對聲明的進行了擴展,現在可以有三種...
    令武閱讀 1,017評論 0 7
  • 一、let 和 constlet:變量聲明, const:只讀常量聲明(聲明的時候賦值)。 let 與 var 的...
    dadage456閱讀 768評論 0 0
  • 原創文章&經驗總結&從校招到A廠一路陽光一路滄桑 詳情請戳www.codercc.com 主要知識點有:var變量...
    你聽___閱讀 656評論 0 1