国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

沒有網(wǎng)站限制的瀏覽器臺(tái)州網(wǎng)站建設(shè)

沒有網(wǎng)站限制的瀏覽器,臺(tái)州網(wǎng)站建設(shè),wordpress查看分類id,c語言精品課程網(wǎng)站開發(fā)😁 作者簡(jiǎn)介:一名大四的學(xué)生,致力學(xué)習(xí)前端開發(fā)技術(shù) ??個(gè)人主頁:夜宵餑餑的主頁 ? 系列專欄:JavaScript進(jìn)階指南 👐學(xué)習(xí)格言:成功不是終點(diǎn),失敗也并非末日,最重要的是繼…

在這里插入圖片描述

😁 作者簡(jiǎn)介:一名大四的學(xué)生,致力學(xué)習(xí)前端開發(fā)技術(shù)
??個(gè)人主頁:夜宵餑餑的主頁
? 系列專欄:JavaScript進(jìn)階指南
👐學(xué)習(xí)格言:成功不是終點(diǎn),失敗也并非末日,最重要的是繼續(xù)前進(jìn)的勇氣

?🔥?前言:

本篇是關(guān)于js中最常用的模塊語法,import和export命令的使用細(xì)節(jié),暴露和導(dǎo)出js語法時(shí)應(yīng)該注意什么,這非常重要,了解到這些細(xì)節(jié),會(huì)讓js語法代碼更加的嚴(yán)謹(jǐn)和健壯,希望可以幫助到大家,歡迎大家的補(bǔ)充和糾正

🌻如果有想要了解模塊加載機(jī)制中具體的實(shí)現(xiàn)可以看我的博客:JavaScript中的模塊Module的加載實(shí)現(xiàn):循環(huán)加載和Node加載

文章目錄

    • 第22章 Module語法
      • 22.1 概述
      • 22.2 嚴(yán)格模式
      • 22.3 export命令
      • 22.4 import命令
      • 22.5 模塊的整體加載
      • 22.6 export defaule命令
      • 22.7 export與import的復(fù)合寫法
      • 22.8 模塊的繼承
      • 22.9 跨模塊常量
      • 22.10 import()
        • 22.10.1 簡(jiǎn)介
        • 22.10.2 適用場(chǎng)合
        • 22.10.3 注意點(diǎn)

第22章 Module語法

22.1 概述

? 在ES6之前,社區(qū)制定了一些模塊加載方案,最主要的有CommonJS和AMD兩種,前者用于服務(wù)器,后者用于瀏覽器。ES6在語言規(guī)格的層面上實(shí)現(xiàn)了模塊功能,而且實(shí)現(xiàn)的相當(dāng)簡(jiǎn)單,完全可以取代現(xiàn)有的CommonJS和AMD規(guī)范,稱為瀏覽器和服務(wù)器通用的模塊解決方案

背景:

? JavaScript一直沒有模塊體系,無法將大程序拆分成互相依賴的小文件,再用簡(jiǎn)單的方法將它們拼裝起來,其他語言都有這項(xiàng)功能,比如Runby的require,Python的import,甚至連CSS都有@import,但是JavaScript沒有任何對(duì)這方面的支持,這對(duì)于開發(fā)大型,復(fù)雜的項(xiàng)目而言是一個(gè)巨大的障礙

? ES6模塊設(shè)計(jì)思想是想盡量靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量,CommonJS和AMD模塊都只能在運(yùn)行是確定這些東西,比如CommonJS模塊就是對(duì)象,輸入時(shí)必須查找對(duì)象屬性

//CommonJS模塊
let {stat,exists,readFile} = require('fs')//等同于
let _fs=require('fs')
let stat=_fs.stat
let exists=_fs.exists
let readfile=_fs.readfile

? 上面代碼的實(shí)質(zhì)是整體加載fs模塊(即加載fs所有的方法),生成一個(gè)對(duì)象(_fs),然后再從這個(gè)對(duì)象上讀取3個(gè)方法,這種加載稱為“運(yùn)行時(shí)加載”,因?yàn)橹挥羞\(yùn)行時(shí)才能得到這個(gè)對(duì)象,導(dǎo)致完全沒辦法在編譯時(shí)進(jìn)行“靜態(tài)優(yōu)化”

? ES6模塊不是對(duì)象,而是通過export命令顯式指定輸出的代碼,再通過import命令輸入

//ES6模塊
import {stat,exists,readFile} from 'fs'

? 上面的代碼的實(shí)質(zhì)是從fs模塊加載3個(gè)方法,而不加載其他方法,這種加載稱為“編譯時(shí)加載”或者靜態(tài)加載,即ES6可以再編譯時(shí)就完成模塊加載,效率比CommonJS模塊的加載方式高,當(dāng)然,這也導(dǎo)致ES6模塊本身無法被引用,因?yàn)樗皇菍?duì)象

? 由于ES6模塊時(shí)編譯時(shí)加載,使得靜態(tài)分析成為可能,有了它就能進(jìn)一步拓展JavaScript的語法,比如引入宏和類型檢驗(yàn)這些只能靠靜態(tài)分析實(shí)現(xiàn)的功能。

? 除了靜態(tài)加載帶來的各種好處,ES6模塊還有以下的好處

  • 不再需要UMD模塊格式,將來服務(wù)器和瀏覽器都會(huì)支持ES6模塊格式
  • 將來瀏覽器的新API可以用模塊格式提供,不再需要做成全局變量
  • 不再需要對(duì)象作為命名空間(Math對(duì)象),未來這些功能可以通過加載模塊來提供

22.2 嚴(yán)格模式

ES的模式自動(dòng)采用嚴(yán)格模式,不過有沒有在模塊頭部加上use strict

嚴(yán)格模式主要有以下限制

  • 變量必須聲明后再使用
  • 函數(shù)的參數(shù)不能有同名屬性,否則報(bào)錯(cuò)
  • 不能使用with語句
  • 不能對(duì)只讀屬性賦值,否則報(bào)錯(cuò)
  • 不能使用前綴0表示八進(jìn)制,否則報(bào)錯(cuò)
  • 不能刪除不可刪除的屬性,否則報(bào)錯(cuò)
  • 不能刪除變量 delete prop,會(huì)報(bào)錯(cuò),只能刪除樹叢delete global[prop]
  • eval不會(huì)再它的外層作用域引入變量
  • eval和arguments不能被重新賦值
  • arguments不會(huì)自動(dòng)反映函數(shù)參數(shù)的變化
  • 不能使用arguments.callee
  • 不能使用arguments.caller
  • 禁止this指向全局對(duì)象
  • 不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
  • 增加保留字(比如protected,static 和 interface)

?? 注意:尤其需要注意this限制,在ES6模塊之中。頂層的this指向undefined,即不應(yīng)該在頂層代碼中使用this

22.3 export命令

1 語法

模塊功能主要有兩個(gè)命令組成:export和import。export命令用于規(guī)定模塊的對(duì)外接口,import命令用于輸入其他模塊提供的功能

一個(gè)模塊就是一個(gè)獨(dú)立文件,該文件內(nèi)部的所有變量,外部無法獲取,如果希望外部能夠讀取模塊內(nèi)部的某個(gè)變量,就必須使用export關(guān)鍵字輸出該變量

  1. 單個(gè)語句,逐條暴露

    //profile.js//輸出變量
    export var firstName='Michael'
    export var lastName='Jackson'
    export var year=1958//輸出函數(shù)或者類
    export fuction multiply(x,y){return x*y
    }
    
  2. 多條語句,統(tǒng)一暴露(?? 推薦這種寫法)

    //profile.jsvar firstName='Michael'var lastName='Jackson'var year=1958export {firstName.lastName,year}
    
  3. 通常情況下,export輸出的變量就是本來的名字,但是可以使用as關(guān)鍵字重命名

    function v1(){}
    function v2(){}export {v1 as streamV1,v2 as streamV2,v2 as streamLatestVersion
    }
    

    上面的代碼使用as關(guān)鍵字重命名了函數(shù)v1和v2的對(duì)外接口,重命名后,v2可以用不同的名字輸出兩次

2. 注意點(diǎn):

  1. export命令規(guī)定的是對(duì)外的接口,必須與模塊內(nèi)部的變量建立一一對(duì)應(yīng)關(guān)系

    //報(bào)錯(cuò)
    export 1;//報(bào)錯(cuò)
    var m =1
    export m;//正確的寫法//寫法一
    export var m=1//寫法二
    var m=1
    export {m}//寫法三
    var m=1
    export{n as m}
    

    上面兩種寫法都會(huì)報(bào)錯(cuò),因?yàn)闆]有提供對(duì)外的接口,第一種寫法直接輸出1,第二種寫法通過變量m依然直接輸出1,1只是一個(gè)值,不是接口

    上面3中寫法都是正確,規(guī)定了對(duì)外的接口m

  2. export語句輸出的接口與其對(duì)應(yīng)的值是動(dòng)態(tài)綁定關(guān)系,即通過該接口可以取到模塊內(nèi)部實(shí)時(shí)的值

    export var foo='bar';
    setTimeout(()=>foo='baz',500)
    

    上面的代碼輸出變量foo,值為bar,500ms之后變成baz

  3. export命令可以出現(xiàn)在模塊的任何位置,只要處于模塊頂層就可以,如果處理塊級(jí)作用域內(nèi),就會(huì)報(bào)錯(cuò),下一節(jié)的import命令也是如此,這是因?yàn)樘幱跅l件代碼塊之中,就沒法做靜態(tài)優(yōu)化,違背模塊設(shè)計(jì)初衷

    function foo(){export default 'bar' //SyntaxError
    }foo()
    

22.4 import命令

1. 語法

使用export命令定義了模塊的對(duì)外接口以后,其他的JS文件就可以通過import命令加載這個(gè)模塊了

//main.js
import {firstName,lastName,year} from './profile'\function setName(element){element.textContent=firstName + ' '+lastName
}

上面的import命令用于加載profile.js文件,并從中輸入變量,import命令接受一個(gè)對(duì)象(用大括號(hào)表示),里面指定要從其他模塊導(dǎo)入的變量名,大括號(hào)中的變量名必須與被導(dǎo)入模塊(profile.js)對(duì)外接口名稱相同

如果想為輸入變量重新去個(gè)名字,要在import命令中使用as關(guān)鍵字,將輸入的變量重命名

import {lastName as surname} from './profile'

如果執(zhí)行所加載的模塊,可以這么寫

import 'lodash'

上面的代碼僅僅執(zhí)行l(wèi)odash模塊,但是不會(huì)輸入任何值

2. 注意點(diǎn):

  1. import 后面的from 指定模塊文件的位置,可以是相對(duì)路徑,也可以是絕對(duì)路徑,.js后綴可以省略,如果只是模塊名,不帶有路徑,那么必須有配置文件告訴JavaScript引擎該模塊的位置

  2. import命令具有提升效果,會(huì)提示到整個(gè)模塊的頭部首先執(zhí)行

    foo()import {foo} from 'my_module'
    
  3. 由于import是靜態(tài)執(zhí)行,所以不能使用表達(dá)式和變量,只有在運(yùn)行是才能得到結(jié)果的語法結(jié)構(gòu)

    //報(bào)錯(cuò)
    import {'f'+'oo'} from 'my_module'//報(bào)錯(cuò)
    let module='my_module'
    import {foo} from module//報(bào)錯(cuò)
    if(x === 1{import {foo} from 'module1
    } else{import {foo} from 'module2'
    }
    
  4. 如果多次重復(fù)執(zhí)行同一句import語句,那么只會(huì)執(zhí)行一次,而不會(huì)執(zhí)行多次

22.5 模塊的整體加載

處理指定加載某個(gè)輸出值,還可以使用整體加載(即星號(hào)*)來指定一個(gè)對(duì)象,所有輸出值都加載在這個(gè)對(duì)象上

//circle.jsexport function area(radius){return Math.PI*radius*radius
}export function circumference(radius){return 2*Math.PI*radius
}//加載模塊,逐一加載
import {area,circumference} from './circle'console.log('圓面積:'+area(4))
console.log('圓周長:'+circumference(14))//統(tǒng)一加載
import * as circle from './circle'console.log('圓面積:'+circle.area(4))
console.log('圓周長:'+circle.circumference(14))

?? 注意:模塊的整體加載所在對(duì)象(上例是circle)應(yīng)該是可以靜態(tài)分析的,所以不允許運(yùn)行時(shí)改變。

import * as circle from './circle'//下面兩行都是不允許的
circle.foo='hello'
circle.area=function(){}

22.6 export defaule命令

? 從前面的例子可以看出來,使用import命令時(shí)用戶需要知道所要加載的變量名或函數(shù)名,否則無法加載,但是,用戶肯定希望快速上手,未必由于閱讀文檔去了解模塊有哪些屬性和方法

? 為了方便用戶,使其不用閱讀文檔就能加載模塊,可以使用export default命令為模塊指定默認(rèn)輸出。

export default function(){console.log('foo')
}import customName from './export-default'
customName() //'foo'

上的代碼中,就不需要知道原模塊輸出的函數(shù)名,需要注意的是,這時(shí)import命令后面不使用大括號(hào),而關(guān)于輸出語句的寫法可以有下面兩種方式

export default function foo(){console.log('foo')
}//或者寫成function foo(){console.log('foo')
}export default foo

上面的代碼中的foo函數(shù)的函數(shù)名foo在模塊外部是無效的,加載時(shí)視為匿名函數(shù)

📝 使用細(xì)節(jié):

  1. export default命令用于指定模塊的默認(rèn)輸出,顯然,一個(gè)模塊只能有一個(gè)默認(rèn)輸出,因此,export default命令只能使用一次,所以import命令后面的才不用加大括號(hào),因?yàn)橹豢赡軐?duì)應(yīng)一個(gè)方法

  2. 如果想在一條import語句中同時(shí)輸入默認(rèn)方法和其他接口,可以寫成下面這樣:

    import _,{each,each as forEach} from 'lodsh'//對(duì)應(yīng)的代碼語句
    export default function(obj){//...
    }export function each(obj,iterator,context){//...
    }export {each as forEach}
    

?? export default語句的本質(zhì)

本質(zhì)上,export default就是輸出一個(gè)叫作default的變量或者方法,然后系統(tǒng)允許我們?yōu)樗∪我饷?#xff0c;所以,下面的寫法是有效的

//modules.js
function add(x,y){return x*y
}
export {add as default}//等同于
//export default add//app.js
import{ default as xxx } from 'modules'
//等同于
import xxx from 'modules'

正是因?yàn)閑xport default命令其實(shí)只是輸出一個(gè)叫作default的變量,所以它后面不能跟變量聲明語句

//正確
export var a=1//正確
var a=1
export default a;//錯(cuò)誤
export default var a=1

上面的代碼中,export default a的含義是將變量a的值賦給變量default,所以最后一種寫法會(huì)報(bào)錯(cuò)

同樣,因?yàn)閑xport default本質(zhì)是將該命令后面的值賦給default變量以后再默認(rèn),所以直接將一個(gè)值寫在export default之后

//正確
export default 42//報(bào)錯(cuò)
export 42

22.7 export與import的復(fù)合寫法

如果模式之中先輸入后輸出同一個(gè)模塊,import語句可以與export語句寫在一起

export {foo,bar} from 'my_module'//等同于
import{foo,bar} from 'my_module'
export {foo,bar}

上面的代碼中,export和import可以結(jié)合寫在一起寫成一行

模塊的接口改名和整體輸出也可以采用這種寫法

//接口改名
export {foo as myFoo} from 'my_module'//整體輸出
export * from 'my_module'

📝 使用細(xì)節(jié):

  1. 默認(rèn)接口的寫法如下:

    export {default} from 'foo'
    
  2. 具名接口改為默認(rèn)接口的寫法如下

    export {es6 as default} from './someModule'//等同于
    import {es6} from './someModule'
    export default es6
    
  3. 默認(rèn)接口也可以改為具名接口

    export {default as es6} from './someModule'
    
  4. 有三種import語句沒有對(duì)應(yīng)的復(fù)合寫法

    import * as someIdentifier from 'someModule'
    import someIdentifier from 'someModule'
    import someIdentifier,{ namedIentifier } from 'someModule'
    

22.8 模塊的繼承

模塊之間也可以繼承

假設(shè)有一個(gè)circleplus模塊繼承了circle模塊

//circleplus.js
export * from 'circle'
export var e=2.718
export default function(x){return Math.exp(x)
}

上面的export * 表示輸出circle模塊的所有屬性和方法

?? 注意:export命令會(huì)忽略circle模塊的default方法,之后,又輸出了自定義的e變量和默認(rèn)方法

加載上面模塊的寫法

import * as math from 'circleplus'
import exp from 'circleplus'
console.log(exp(math.e))

上面代碼中的import exp表示,將circleplus模塊的默認(rèn)方法加載為exp方法

22.9 跨模塊常量

前面介紹const 命令的時(shí)候說過,const聲明的常量只能在當(dāng)前代碼塊內(nèi)有效,如果想設(shè)置跨模塊的常量(即跨多個(gè)文件),或者說一個(gè)值、要被多個(gè)模塊共享,可以采用下面的寫法

//constants.js模塊
export const A=1
export const B=2
export const C=3//test1.js模塊
import * as constants from './constants'
console.log(constants.A) //1
console.log(constants.B) //2//test2.js模塊
import {A,B} from './constants'
console.log(A) //1
console.log(C) //3

🌻 小建議:如果要使用的常量非常多,可以建立一個(gè)專門的constants目錄,將各種常量寫在不同的文件里面并保存在該目錄下

export const db={url:'https://www.csdn.net/',admin_username:'夜宵餑餑',admin_password:'xxxxxxxx'
}//constants/user.jd
export const users=['root','admin','staff','cex','chief']

然后將這些文件輸出的常量合并在index.js中

//constants/index.js
export {db} from './db'
export {user} from './users'

使用的時(shí)候,直接加載index.js即可

//script.js
import {db,users} from './constants'

22.10 import()

22.10.1 簡(jiǎn)介

import命令會(huì)被JavaScript引擎靜態(tài)分析,先于模塊內(nèi)的其他模塊執(zhí)行(稱為連接更合適),所以下面的代碼會(huì)報(bào)錯(cuò)

//報(bào)錯(cuò)
if(x === 2){import MyModule from './myModule'
}

上面的代碼中,引擎處理import語句是在編譯時(shí),這時(shí)不會(huì)分析或執(zhí)行if語句,所以import語句放在if代碼塊之中毫無意義,因此會(huì)報(bào)句法錯(cuò)誤,而不是執(zhí)行時(shí)錯(cuò)誤

這樣的設(shè)計(jì)固然有利于編譯器提高效率,但也導(dǎo)致無法在運(yùn)行時(shí)加載模塊。在語法上,條件加載不可能實(shí)現(xiàn)。

因此,有一個(gè)提案(現(xiàn)已經(jīng)實(shí)現(xiàn)),建議引入import()函數(shù),完成動(dòng)態(tài)加載。

import(specifier)

import函數(shù)的參數(shù)specifier指定要加載的模塊的位置,import命令能夠接受什么參數(shù),import()函數(shù)就可以接受什么參數(shù),后者為動(dòng)態(tài)加載。

import()函數(shù)返回一個(gè)Promise對(duì)象,下面是一個(gè)例子

const main=document.querySelector('main')import('./section-module/${someVariable}.js')
.then(module => {module.loadPageInto(main)
})
.catch(err => {main.textContent=err.message
})

import()函數(shù)可以用在任何地方,不僅僅是模塊,非模塊的腳本也可以使用,它是運(yùn)行時(shí)執(zhí)行,也就是說,運(yùn)行到這一句便會(huì)加載模塊。另外,import()函數(shù)所加載的模塊沒有靜態(tài)連接關(guān)系,這點(diǎn)也與import語句不相同

22.10.2 適用場(chǎng)合
  1. 按需加載

    button.addEventListener('click',event=>{import('./dialogBox.js').then(dialogBox => {dialogBox.open()}).catch(error => {//Error})
    })
    
  2. 條件加載

    if(condition){import('moduleA').then(...)
    }else{import('moduleB').then(...)
    }
    
  3. 動(dòng)態(tài)加載模塊路徑

    import(f()).then(...)
    
22.10.3 注意點(diǎn)
  1. import()加載模塊成功以后,這個(gè)模塊會(huì)作為一個(gè)對(duì)象當(dāng)作then方法的參數(shù),因此可以使用對(duì)象結(jié)構(gòu)賦值的語法,獲取輸出接口

  2. 如果模塊有default輸出接口,可以用參數(shù)直接獲得

    import('./myModule.js').then(myModule => {console.log(myModule.default)
    })//也可以使用具名形式輸入
    import('./myModule.js').then(({default:thenDefault}) => {console.log(thenDefault)
    })
    
  3. 如果想同時(shí)加載多個(gè)模塊,可以采用Promise.all寫法

    Promise.all([import('./amo.js'),import('./bmo.js'),import('./cmo.js')
    ])
    .then(([amo,bmo,cmo])=>{})
    
  4. import也可以用在async函數(shù)中

http://aloenet.com.cn/news/28238.html

相關(guān)文章:

  • 汕頭網(wǎng)絡(luò)公司網(wǎng)站建設(shè)朝陽網(wǎng)站seo
  • 做烘培的網(wǎng)站有哪些b2b網(wǎng)站推廣優(yōu)化
  • 什么網(wǎng)站做優(yōu)化最好外貿(mào)網(wǎng)站平臺(tái)哪個(gè)好
  • 企業(yè)發(fā)展歷程網(wǎng)站關(guān)鍵詞優(yōu)化怎么操作
  • 恐怖音樂怎么做的視頻網(wǎng)站公司網(wǎng)絡(luò)營銷推廣方案
  • 電商網(wǎng)站開發(fā)教材唐山seo
  • 學(xué)院網(wǎng)站建設(shè)管理規(guī)章制度谷歌瀏覽器官網(wǎng)入口
  • 網(wǎng)站開發(fā)功能需求表下載班級(jí)優(yōu)化大師并安裝
  • 煙臺(tái)中企動(dòng)力提供網(wǎng)站建設(shè)游戲推廣論壇
  • 做設(shè)計(jì)的都用那些網(wǎng)站seo基礎(chǔ)知識(shí)
  • 推廣型網(wǎng)站建設(shè)電話百度開戶需要什么資質(zhì)
  • 漯河企業(yè)網(wǎng)站建設(shè)公司軟文廣告示范
  • 英文書 影印版 網(wǎng)站開發(fā)廈門人才網(wǎng)個(gè)人會(huì)員
  • 中國那個(gè)公司的網(wǎng)站做的最好看有什么平臺(tái)可以推廣
  • 菏澤建設(shè)局網(wǎng)站網(wǎng)絡(luò)視頻營銷平臺(tái)
  • 招商加盟類網(wǎng)站模板網(wǎng)站建設(shè)費(fèi)用
  • 手機(jī)做網(wǎng)站用什么軟件灰色詞排名推廣
  • 微小店網(wǎng)站建設(shè)平臺(tái)網(wǎng)絡(luò)營銷推廣方案策劃
  • 做網(wǎng)站的要花多少錢推廣普通話作文
  • 低價(jià)網(wǎng)站建設(shè)行業(yè)現(xiàn)狀win10優(yōu)化軟件哪個(gè)好
  • 徐州網(wǎng)站優(yōu)化品牌宣傳如何做
  • 建站需要哪些東西武漢網(wǎng)絡(luò)營銷推廣
  • 住房和城鄉(xiāng)建設(shè)廳網(wǎng)站辦事大廳百度小程序?qū)W(wǎng)站seo
  • 網(wǎng)站空間購買長沙關(guān)鍵詞優(yōu)化方法
  • 雄安網(wǎng)站建設(shè)公司百度純凈版首頁入口
  • 朝陽周邊網(wǎng)站建設(shè)對(duì)seo的認(rèn)識(shí)和理解
  • 怎么上傳網(wǎng)站地圖seo外包公司哪家專業(yè)
  • 自己做網(wǎng)站要會(huì)什么軟件怎么弄屬于自己的網(wǎng)站
  • 科技網(wǎng)站設(shè)計(jì)公司有哪些北京外貿(mào)網(wǎng)站優(yōu)化
  • 播視頻網(wǎng)站開發(fā)seo是什么意思中文