深入理解 ES6

let && const

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

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

可以發(fā)現(xiàn)在聲明前使用let聲明的變量會(huì)導(dǎo)致報(bào)錯(cuò),這解決了 JS 很多奇怪的問題。并且使用let會(huì)生成一個(gè)塊級(jí)作用域,作用域外不能訪問該變量。

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

在 JS 中,聲明變量都會(huì)提升,不論用什么關(guān)鍵字聲明。當(dāng)使用let時(shí)變量也會(huì)被提升至塊級(jí)作用域的頂部,但是只提升聲明,不提升初始化。并且會(huì)產(chǎn)生臨時(shí)死區(qū),該區(qū)域會(huì)存放變量,直到執(zhí)行過聲明語句后,方可使用該變量。

在循環(huán)中l(wèi)et會(huì)與前面有些不同,每次迭代都會(huì)產(chǎn)生一個(gè)新的變量,并用之前的值初始化,如何理解這句話呢,請(qǐng)看以下代碼。

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

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

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

當(dāng)然了,有辦法讓這個(gè)不能改變

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

但是Object.freeze只能在這里有效,對(duì)于數(shù)組這些可以看看這個(gè)提案。

這兩個(gè)新的聲明方式在全局作用域下不會(huì)自動(dòng)加上window

字符串相關(guān)

部分新增的字符串函數(shù)

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

模板字面量

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

// 語法就是 `` 代替之前的引號(hào),在 `` 中使用引號(hào)不需要轉(zhuǎn)義lets =`it's string`

多行字符串

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

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

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

占位符和標(biāo)簽?zāi)0?/p>

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

函數(shù)

默認(rèn)參數(shù)

ES6 允許給函數(shù)增加默認(rèn)參數(shù)

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

新增函數(shù)內(nèi)部方法

在 JS 中,函數(shù)有多種用法,可以直接調(diào)用,也可以通過new構(gòu)造函數(shù)。

在 ES6中,函數(shù)內(nèi)部新增了 [[Call]] 和 [[Construct]] 兩個(gè)方法。后者會(huì)在使用new構(gòu)造函數(shù)時(shí)執(zhí)行,其他情況會(huì)執(zhí)行前者方法。

當(dāng)一個(gè)函數(shù)必須使用new構(gòu)造時(shí),你可以使用這個(gè)新屬性new.target判斷

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

箭頭函數(shù)

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

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

箭頭函數(shù)和普通函數(shù)區(qū)別還是蠻大的,說幾個(gè)常用的

沒有this,不能改變this綁定

不能通過new調(diào)用,當(dāng)然也沒有原型

沒有arguments對(duì)象,不能有相同命名參數(shù)

箭頭函數(shù)雖然沒有this,但是還是可以在內(nèi)部使用this的

this的綁定取決于定義函數(shù)時(shí)的上下文環(huán)境

一旦函數(shù)調(diào)用,任何改變this的方法都無效

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

對(duì)象相關(guān)

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

ES6 也新增了幾個(gè)對(duì)象方法

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

原型相關(guān)

ES6 之前改變對(duì)象原型很麻煩

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 不是每個(gè)函數(shù)都可以使用的,只有在函數(shù)的簡(jiǎn)寫語法中方可使用。因?yàn)樵?ES6中新增了一個(gè)函數(shù)內(nèi)部屬性 [[HomeObject]],這個(gè)屬性決定了是否可以訪問到super。首先在該屬性上調(diào)用Object.getPrototypeOf(綁定的對(duì)象),然后找到原型中的同名函數(shù),在設(shè)置this綁定并且調(diào)用函數(shù),其實(shí)就是一個(gè)新增的語法糖。

解構(gòu)賦值

該特性可以用于對(duì)象,數(shù)組和傳參。

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

Symbol

ES6 新出的第六個(gè)原始類型。多用于避免代碼沖突,作為一個(gè)私有屬性使用,不會(huì)被屬性遍歷出來??梢允褂肙bject.getOwnPropertySymbols()檢索 Symbol 屬性。

創(chuàng)建和使用

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

暴露內(nèi)部操作

Symbol 中預(yù)定義了一些 well-know Symbol,這些 Symbol 定義了一些語言的內(nèi)部實(shí)現(xiàn)

Symbol.hasinstance,用于執(zhí)行instanceof時(shí)檢測(cè)對(duì)象的繼承信息

Symbol.isConcatSpreadable,布爾值,用于判斷當(dāng)使用concat函數(shù)時(shí)是否將數(shù)組展開

Symbol.iterator,迭代器,后面會(huì)講到

Symbol.match,Symbol.replace,Symbol.search,Symbol.split,字符串相關(guān)方法的對(duì)應(yīng)內(nèi)部實(shí)現(xiàn)

Symbol.toPrimitive,返回對(duì)象原始值

Symbol.toStringTag,調(diào)用toString

Set 和 Map

Set

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

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

Map

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

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

迭代器和 Generator 函數(shù)

迭代器

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

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

對(duì)于自己創(chuàng)建的對(duì)象都是不可迭代的,當(dāng)然我們也可以讓他變成迭代的

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

Generator 函數(shù)

用于異步編程。該函數(shù)可以暫停和恢復(fù)執(zhí)行,和同步寫法很像。

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

接下來看下 Generator 函數(shù)如何用于異步

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

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

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

類聲明相比之前的寫法有以下幾點(diǎn)優(yōu)點(diǎn)

類聲明和 let 聲明一樣,有臨時(shí)死區(qū)

類聲明中的代碼全部運(yùn)行在嚴(yán)格模式下

必須使用 new 調(diào)用

繼承

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

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

Promise

概念

用于異步編程。

// 你可以使用 new 創(chuàng)建一個(gè) Promise 對(duì)象letpromise =newPromise(function(resolve, reject)){}resole()// 代表成功reject()// 代表失敗promise.then(onFulfilled, onRejected)// 當(dāng)調(diào)用 resole 或者 reject ,then 可以監(jiān)聽到promise.catch()// reject 或者 throw時(shí)可以監(jiān)聽到

Promise 有三個(gè)狀態(tài)

pending,等待狀態(tài),也就是既不是 resolve 也不是 reject 狀態(tài)

fulfilled,resolve 以后進(jìn)入這個(gè)狀態(tài)

reject,reject 以后進(jìn)入這個(gè)狀態(tài)

一般使用情況

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

以上是最常用的 Promise 寫法,現(xiàn)在介紹 Promise 鏈

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

Promise 高級(jí)用法

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

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

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

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

Proxy

Proxy 可以創(chuàng)建一個(gè)代替目標(biāo)對(duì)象的代理,攔截語言內(nèi)部的操作。

lethandle = {}lettarget = {}// 這樣就創(chuàng)建了target 對(duì)象的代理,但是這個(gè)代理其實(shí)沒有任何用處letp =newProxy(target, handle)

上面的代碼中可以看到傳入了一個(gè)handle的對(duì)象,只有當(dāng)這個(gè)對(duì)象中包含一些代理行為的函數(shù)時(shí),這個(gè)代理才有用。具有的代理行為函數(shù)可以去MDN查看,這里舉例幾個(gè)用法。

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

模塊化

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一章:塊級(jí)作用域綁定 塊級(jí)聲明 1.var聲明及變量提升機(jī)制:在函數(shù)作用域或者全局作用域中通過關(guān)鍵字var聲明的...
    BeADre_wang閱讀 996評(píng)論 0 0
  • *node下用express框架,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的mvc *構(gòu)建工具:gulp / babel / webpack ...
    韓娜愛吃辣_前端程序媛閱讀 1,203評(píng)論 0 1
  • 1、新的聲明方式 以前我們?cè)诼暶鲿r(shí)只有一種方法,就是使用var來進(jìn)行聲明,ES6對(duì)聲明的進(jìn)行了擴(kuò)展,現(xiàn)在可以有三種...
    令武閱讀 1,090評(píng)論 0 7
  • 一、let 和 constlet:變量聲明, const:只讀常量聲明(聲明的時(shí)候賦值)。 let 與 var 的...
    dadage456閱讀 837評(píng)論 0 0
  • 原創(chuàng)文章&經(jīng)驗(yàn)總結(jié)&從校招到A廠一路陽光一路滄桑 詳情請(qǐng)戳www.codercc.com 主要知識(shí)點(diǎn)有:var變量...
    你聽___閱讀 704評(píng)論 0 1

友情鏈接更多精彩內(nèi)容