武城网站建设公司,网络营销方法有几种类型,个人业务网站免费制作,怎么做电影网站app#x1f601; 作者简介#xff1a;一名大四的学生#xff0c;致力学习前端开发技术 ⭐️个人主页#xff1a;夜宵饽饽的主页 ❔ 系列专栏#xff1a;JavaScript进阶指南 #x1f450;学习格言#xff1a;成功不是终点#xff0c;失败也并非末日#xff0c;最重要的是继… 作者简介一名大四的学生致力学习前端开发技术 ⭐️个人主页夜宵饽饽的主页 ❔ 系列专栏JavaScript进阶指南 学习格言成功不是终点失败也并非末日最重要的是继续前进的勇气 前言 本篇是关于js中最常用的模块语法import和export命令的使用细节暴露和导出js语法时应该注意什么这非常重要了解到这些细节会让js语法代码更加的严谨和健壮希望可以帮助到大家欢迎大家的补充和纠正 如果有想要了解模块加载机制中具体的实现可以看我的博客JavaScript中的模块Module的加载实现循环加载和Node加载 文章目录 第22章 Module语法22.1 概述22.2 严格模式22.3 export命令22.4 import命令22.5 模块的整体加载22.6 export defaule命令22.7 export与import的复合写法22.8 模块的继承22.9 跨模块常量22.10 import()22.10.1 简介22.10.2 适用场合22.10.3 注意点 第22章 Module语法
22.1 概述
在ES6之前社区制定了一些模块加载方案最主要的有CommonJS和AMD两种前者用于服务器后者用于浏览器。ES6在语言规格的层面上实现了模块功能而且实现的相当简单完全可以取代现有的CommonJS和AMD规范称为浏览器和服务器通用的模块解决方案 背景 JavaScript一直没有模块体系无法将大程序拆分成互相依赖的小文件再用简单的方法将它们拼装起来其他语言都有这项功能比如Runby的requirePython的import甚至连CSS都有import但是JavaScript没有任何对这方面的支持这对于开发大型复杂的项目而言是一个巨大的障碍 ES6模块设计思想是想尽量静态化使得编译时就能确定模块的依赖关系以及输入和输出的变量CommonJS和AMD模块都只能在运行是确定这些东西比如CommonJS模块就是对象输入时必须查找对象属性
//CommonJS模块
let {stat,exists,readFile} require(fs)//等同于
let _fsrequire(fs)
let stat_fs.stat
let exists_fs.exists
let readfile_fs.readfile 上面代码的实质是整体加载fs模块即加载fs所有的方法),生成一个对象_fs)然后再从这个对象上读取3个方法这种加载称为“运行时加载”因为只有运行时才能得到这个对象导致完全没办法在编译时进行“静态优化”
ES6模块不是对象而是通过export命令显式指定输出的代码再通过import命令输入
//ES6模块
import {stat,exists,readFile} from fs 上面的代码的实质是从fs模块加载3个方法而不加载其他方法这种加载称为“编译时加载”或者静态加载即ES6可以再编译时就完成模块加载效率比CommonJS模块的加载方式高当然这也导致ES6模块本身无法被引用因为它不是对象
由于ES6模块时编译时加载使得静态分析成为可能有了它就能进一步拓展JavaScript的语法比如引入宏和类型检验这些只能靠静态分析实现的功能。
除了静态加载带来的各种好处ES6模块还有以下的好处
不再需要UMD模块格式将来服务器和浏览器都会支持ES6模块格式将来浏览器的新API可以用模块格式提供不再需要做成全局变量不再需要对象作为命名空间Math对象,未来这些功能可以通过加载模块来提供
22.2 严格模式
ES的模式自动采用严格模式不过有没有在模块头部加上use strict
严格模式主要有以下限制
变量必须声明后再使用函数的参数不能有同名属性否则报错不能使用with语句不能对只读属性赋值否则报错不能使用前缀0表示八进制否则报错不能删除不可删除的属性否则报错不能删除变量 delete prop会报错只能删除树丛delete global[prop]eval不会再它的外层作用域引入变量eval和arguments不能被重新赋值arguments不会自动反映函数参数的变化不能使用arguments.callee不能使用arguments.caller禁止this指向全局对象不能使用fn.caller和fn.arguments获取函数调用的堆栈增加保留字比如protected,static 和 interface)
❗️ 注意尤其需要注意this限制在ES6模块之中。顶层的this指向undefined即不应该在顶层代码中使用this
22.3 export命令
1 语法
模块功能主要有两个命令组成export和import。export命令用于规定模块的对外接口import命令用于输入其他模块提供的功能
一个模块就是一个独立文件该文件内部的所有变量外部无法获取如果希望外部能够读取模块内部的某个变量就必须使用export关键字输出该变量 单个语句逐条暴露 //profile.js//输出变量
export var firstNameMichael
export var lastNameJackson
export var year1958//输出函数或者类
export fuction multiply(x,y){return x*y
}多条语句统一暴露⭐️ 推荐这种写法 //profile.jsvar firstNameMichaelvar lastNameJacksonvar year1958export {firstName.lastName,year}通常情况下export输出的变量就是本来的名字但是可以使用as关键字重命名 function v1(){}
function v2(){}export {v1 as streamV1,v2 as streamV2,v2 as streamLatestVersion
}上面的代码使用as关键字重命名了函数v1和v2的对外接口重命名后v2可以用不同的名字输出两次
2. 注意点 export命令规定的是对外的接口必须与模块内部的变量建立一一对应关系 //报错
export 1;//报错
var m 1
export m;//正确的写法//写法一
export var m1//写法二
var m1
export {m}//写法三
var m1
export{n as m}上面两种写法都会报错因为没有提供对外的接口第一种写法直接输出1第二种写法通过变量m依然直接输出11只是一个值不是接口 上面3中写法都是正确规定了对外的接口m export语句输出的接口与其对应的值是动态绑定关系即通过该接口可以取到模块内部实时的值 export var foobar;
setTimeout(()foobaz,500)上面的代码输出变量foo值为bar500ms之后变成baz export命令可以出现在模块的任何位置只要处于模块顶层就可以如果处理块级作用域内就会报错下一节的import命令也是如此这是因为处于条件代码块之中就没法做静态优化违背模块设计初衷 function foo(){export default bar //SyntaxError
}foo()22.4 import命令
1. 语法
使用export命令定义了模块的对外接口以后其他的JS文件就可以通过import命令加载这个模块了
//main.js
import {firstName,lastName,year} from ./profile\function setName(element){element.textContentfirstName lastName
}上面的import命令用于加载profile.js文件并从中输入变量import命令接受一个对象用大括号表示里面指定要从其他模块导入的变量名大括号中的变量名必须与被导入模块profile.js)对外接口名称相同
如果想为输入变量重新去个名字要在import命令中使用as关键字将输入的变量重命名
import {lastName as surname} from ./profile如果执行所加载的模块可以这么写
import lodash上面的代码仅仅执行lodash模块但是不会输入任何值
2. 注意点 import 后面的from 指定模块文件的位置可以是相对路径也可以是绝对路径.js后缀可以省略如果只是模块名不带有路径那么必须有配置文件告诉JavaScript引擎该模块的位置 import命令具有提升效果会提示到整个模块的头部首先执行 foo()import {foo} from my_module由于import是静态执行所以不能使用表达式和变量只有在运行是才能得到结果的语法结构 //报错
import {foo} from my_module//报错
let modulemy_module
import {foo} from module//报错
if(x 1{import {foo} from module1
} else{import {foo} from module2
}如果多次重复执行同一句import语句那么只会执行一次而不会执行多次
22.5 模块的整体加载
处理指定加载某个输出值还可以使用整体加载即星号*来指定一个对象所有输出值都加载在这个对象上
//circle.jsexport function area(radius){return Math.PI*radius*radius
}export function circumference(radius){return 2*Math.PI*radius
}//加载模块逐一加载
import {area,circumference} from ./circleconsole.log(圆面积area(4))
console.log(圆周长circumference(14))//统一加载
import * as circle from ./circleconsole.log(圆面积circle.area(4))
console.log(圆周长circle.circumference(14))❗️ 注意模块的整体加载所在对象上例是circle应该是可以静态分析的所以不允许运行时改变。
import * as circle from ./circle//下面两行都是不允许的
circle.foohello
circle.areafunction(){}22.6 export defaule命令
从前面的例子可以看出来使用import命令时用户需要知道所要加载的变量名或函数名否则无法加载但是用户肯定希望快速上手未必由于阅读文档去了解模块有哪些属性和方法
为了方便用户使其不用阅读文档就能加载模块可以使用export default命令为模块指定默认输出。
export default function(){console.log(foo)
}import customName from ./export-default
customName() //foo上的代码中就不需要知道原模块输出的函数名需要注意的是这时import命令后面不使用大括号而关于输出语句的写法可以有下面两种方式
export default function foo(){console.log(foo)
}//或者写成function foo(){console.log(foo)
}export default foo上面的代码中的foo函数的函数名foo在模块外部是无效的加载时视为匿名函数 使用细节 export default命令用于指定模块的默认输出显然一个模块只能有一个默认输出因此export default命令只能使用一次所以import命令后面的才不用加大括号因为只可能对应一个方法 如果想在一条import语句中同时输入默认方法和其他接口可以写成下面这样 import _,{each,each as forEach} from lodsh//对应的代码语句
export default function(obj){//...
}export function each(obj,iterator,context){//...
}export {each as forEach}⭐️ export default语句的本质
本质上export default就是输出一个叫作default的变量或者方法然后系统允许我们为它取任意名字所以下面的写法是有效的
//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正是因为export default命令其实只是输出一个叫作default的变量所以它后面不能跟变量声明语句
//正确
export var a1//正确
var a1
export default a;//错误
export default var a1上面的代码中export default a的含义是将变量a的值赋给变量default所以最后一种写法会报错
同样因为export default本质是将该命令后面的值赋给default变量以后再默认所以直接将一个值写在export default之后
//正确
export default 42//报错
export 4222.7 export与import的复合写法
如果模式之中先输入后输出同一个模块import语句可以与export语句写在一起
export {foo,bar} from my_module//等同于
import{foo,bar} from my_module
export {foo,bar}上面的代码中export和import可以结合写在一起写成一行
模块的接口改名和整体输出也可以采用这种写法
//接口改名
export {foo as myFoo} from my_module//整体输出
export * from my_module使用细节 默认接口的写法如下 export {default} from foo具名接口改为默认接口的写法如下 export {es6 as default} from ./someModule//等同于
import {es6} from ./someModule
export default es6默认接口也可以改为具名接口 export {default as es6} from ./someModule有三种import语句没有对应的复合写法 import * as someIdentifier from someModule
import someIdentifier from someModule
import someIdentifier,{ namedIentifier } from someModule22.8 模块的继承
模块之间也可以继承
假设有一个circleplus模块继承了circle模块
//circleplus.js
export * from circle
export var e2.718
export default function(x){return Math.exp(x)
}上面的export * 表示输出circle模块的所有属性和方法
❗️ 注意export命令会忽略circle模块的default方法之后又输出了自定义的e变量和默认方法
加载上面模块的写法
import * as math from circleplus
import exp from circleplus
console.log(exp(math.e))上面代码中的import exp表示将circleplus模块的默认方法加载为exp方法
22.9 跨模块常量
前面介绍const 命令的时候说过const声明的常量只能在当前代码块内有效如果想设置跨模块的常量即跨多个文件或者说一个值、要被多个模块共享可以采用下面的写法
//constants.js模块
export const A1
export const B2
export const C3//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小建议如果要使用的常量非常多可以建立一个专门的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使用的时候直接加载index.js即可
//script.js
import {db,users} from ./constants22.10 import()
22.10.1 简介
import命令会被JavaScript引擎静态分析先于模块内的其他模块执行称为连接更合适所以下面的代码会报错
//报错
if(x 2){import MyModule from ./myModule
}上面的代码中引擎处理import语句是在编译时这时不会分析或执行if语句所以import语句放在if代码块之中毫无意义因此会报句法错误而不是执行时错误
这样的设计固然有利于编译器提高效率但也导致无法在运行时加载模块。在语法上条件加载不可能实现。
因此有一个提案现已经实现建议引入import()函数完成动态加载。
import(specifier)import函数的参数specifier指定要加载的模块的位置import命令能够接受什么参数import()函数就可以接受什么参数后者为动态加载。
import()函数返回一个Promise对象下面是一个例子
const maindocument.querySelector(main)import(./section-module/${someVariable}.js)
.then(module {module.loadPageInto(main)
})
.catch(err {main.textContenterr.message
})import()函数可以用在任何地方不仅仅是模块非模块的脚本也可以使用它是运行时执行也就是说运行到这一句便会加载模块。另外import()函数所加载的模块没有静态连接关系这点也与import语句不相同
22.10.2 适用场合 按需加载 button.addEventListener(click,event{import(./dialogBox.js).then(dialogBox {dialogBox.open()}).catch(error {//Error})
})条件加载 if(condition){import(moduleA).then(...)
}else{import(moduleB).then(...)
}动态加载模块路径 import(f()).then(...)22.10.3 注意点 import()加载模块成功以后这个模块会作为一个对象当作then方法的参数因此可以使用对象结构赋值的语法获取输出接口 如果模块有default输出接口可以用参数直接获得 import(./myModule.js).then(myModule {console.log(myModule.default)
})//也可以使用具名形式输入
import(./myModule.js).then(({default:thenDefault}) {console.log(thenDefault)
})如果想同时加载多个模块可以采用Promise.all写法 Promise.all([import(./amo.js),import(./bmo.js),import(./cmo.js)
])
.then(([amo,bmo,cmo]){})import也可以用在async函数中 文章转载自: http://www.morning.kqpsj.cn.gov.cn.kqpsj.cn http://www.morning.fjlsfs.com.gov.cn.fjlsfs.com http://www.morning.glxmf.cn.gov.cn.glxmf.cn http://www.morning.jppdk.cn.gov.cn.jppdk.cn http://www.morning.rqbr.cn.gov.cn.rqbr.cn http://www.morning.rfmzs.cn.gov.cn.rfmzs.cn http://www.morning.dkfrd.cn.gov.cn.dkfrd.cn http://www.morning.ljygq.cn.gov.cn.ljygq.cn http://www.morning.pnfwd.cn.gov.cn.pnfwd.cn http://www.morning.lxfdh.cn.gov.cn.lxfdh.cn http://www.morning.pghgq.cn.gov.cn.pghgq.cn http://www.morning.hxrg.cn.gov.cn.hxrg.cn http://www.morning.mkccd.cn.gov.cn.mkccd.cn http://www.morning.fpkdd.cn.gov.cn.fpkdd.cn http://www.morning.glnmm.cn.gov.cn.glnmm.cn http://www.morning.ghccq.cn.gov.cn.ghccq.cn http://www.morning.qkbwd.cn.gov.cn.qkbwd.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.wcczg.cn.gov.cn.wcczg.cn http://www.morning.mxftp.com.gov.cn.mxftp.com http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.fqklt.cn.gov.cn.fqklt.cn http://www.morning.lsqxh.cn.gov.cn.lsqxh.cn http://www.morning.bpmfr.cn.gov.cn.bpmfr.cn http://www.morning.tgpgx.cn.gov.cn.tgpgx.cn http://www.morning.rjmd.cn.gov.cn.rjmd.cn http://www.morning.jqrhz.cn.gov.cn.jqrhz.cn http://www.morning.hwnnm.cn.gov.cn.hwnnm.cn http://www.morning.weiwt.com.gov.cn.weiwt.com http://www.morning.qllcp.cn.gov.cn.qllcp.cn http://www.morning.lwyqd.cn.gov.cn.lwyqd.cn http://www.morning.wnqfz.cn.gov.cn.wnqfz.cn http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn http://www.morning.mcwgn.cn.gov.cn.mcwgn.cn http://www.morning.tfznk.cn.gov.cn.tfznk.cn http://www.morning.bfmq.cn.gov.cn.bfmq.cn http://www.morning.xlbtz.cn.gov.cn.xlbtz.cn http://www.morning.irqlul.cn.gov.cn.irqlul.cn http://www.morning.czlzn.cn.gov.cn.czlzn.cn http://www.morning.mcpdn.cn.gov.cn.mcpdn.cn http://www.morning.qbccg.cn.gov.cn.qbccg.cn http://www.morning.fhlfp.cn.gov.cn.fhlfp.cn http://www.morning.errnull.com.gov.cn.errnull.com http://www.morning.ysrtj.cn.gov.cn.ysrtj.cn http://www.morning.cctgww.cn.gov.cn.cctgww.cn http://www.morning.burpgr.cn.gov.cn.burpgr.cn http://www.morning.mpgfk.cn.gov.cn.mpgfk.cn http://www.morning.fesiy.com.gov.cn.fesiy.com http://www.morning.cwqln.cn.gov.cn.cwqln.cn http://www.morning.bwmm.cn.gov.cn.bwmm.cn http://www.morning.gzxnj.cn.gov.cn.gzxnj.cn http://www.morning.rxcqt.cn.gov.cn.rxcqt.cn http://www.morning.ryrgx.cn.gov.cn.ryrgx.cn http://www.morning.rynq.cn.gov.cn.rynq.cn http://www.morning.qsdnt.cn.gov.cn.qsdnt.cn http://www.morning.bnpn.cn.gov.cn.bnpn.cn http://www.morning.qqklk.cn.gov.cn.qqklk.cn http://www.morning.lzqdd.cn.gov.cn.lzqdd.cn http://www.morning.nkhdt.cn.gov.cn.nkhdt.cn http://www.morning.spdyl.cn.gov.cn.spdyl.cn http://www.morning.tbqbd.cn.gov.cn.tbqbd.cn http://www.morning.stlgg.cn.gov.cn.stlgg.cn http://www.morning.dmxzd.cn.gov.cn.dmxzd.cn http://www.morning.yqlrq.cn.gov.cn.yqlrq.cn http://www.morning.lsbjj.cn.gov.cn.lsbjj.cn http://www.morning.smdnl.cn.gov.cn.smdnl.cn http://www.morning.mglqf.cn.gov.cn.mglqf.cn http://www.morning.csnch.cn.gov.cn.csnch.cn http://www.morning.fswml.cn.gov.cn.fswml.cn http://www.morning.fmry.cn.gov.cn.fmry.cn http://www.morning.jlpdc.cn.gov.cn.jlpdc.cn http://www.morning.spnky.cn.gov.cn.spnky.cn http://www.morning.sbjbs.cn.gov.cn.sbjbs.cn http://www.morning.zkqjz.cn.gov.cn.zkqjz.cn http://www.morning.tbcfj.cn.gov.cn.tbcfj.cn http://www.morning.qgmwt.cn.gov.cn.qgmwt.cn http://www.morning.mjtft.cn.gov.cn.mjtft.cn http://www.morning.qkrqt.cn.gov.cn.qkrqt.cn http://www.morning.htpjl.cn.gov.cn.htpjl.cn http://www.morning.rzbgn.cn.gov.cn.rzbgn.cn