原生JavaScript中如何用关键字import和export来实现一个模块接口

这篇文章将为大家详细讲解有关原生JavaScript中如何用关键字import和export来实现一个模块接口,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

创新互联建站于2013年开始,公司以成都网站制作、成都网站设计、系统开发、网络推广、文化传媒、企业宣传、平面广告设计等为主要业务,适用行业近百种。服务企业客户上1000+,涉及国内多个省份客户。拥有多年网站建设开发经验。为企业提供专业的网站建设、创意设计、宣传推广等服务。 通过专业的设计、独特的风格,为不同客户提供各种风格的特色服务。

在互联网的洪荒时代,网站主要用 HTML和 CSS 开发的。如果将 JavaScript 加载到页面中,通常是以小片段的形式提供效果和交互,一般会把所有的  JavaScript 代码全都写在一个文件中,并加载到一个 script 标签中。尽管可以把 JavaScript  拆分为多个文件,但是所有的变量和函数仍然会被添加到全局作用域中。

但是后来 JavaScript  在浏览器中发挥着重要的作用,迫切需要使用第三方代码来完成常见任务,并且需要把代码分解为模块化的文件,避免污染全局命名空间。

ECMAScript 2015 规范在 JavaScript 语言中引入了 module,也有了 import 和 export  语句。在本文中,我们一起来学习 JavaScript 模块,以及怎样用 import 和 export 来组织代码。

模块化编程

在 JavaScript  中出现模块的概念之前,当我们想要把自己的代码组织为多个块时,一般会创建多个文件,并且将它们链接为单独的脚本。下面先举例说明,首先创建一个 index.html  文件和两个JavaScript文件“ functions.js 和 script.js。

index.html 文件用来显示两个数字的和、差、乘积和商,并链接到 script 标签中的两个 JavaScript 文件。打开 index.html  并添加以下代码:

index.html

                    JavaScript Modules            

Answers

     

 and 

      

Addition

     

      

Subtraction

     

      

Multiplication

     

      

Division

     

               

这个页面很简单,就不详细说明了。

functions.js 文件中包含将会在第二个脚本中用到的数学函数。打开文件并添加以下内容:

functions.js

function sum(x, y) {   return x + y }  function difference(x, y) {   return x - y }  function product(x, y) {   return x * y }  function quotient(x, y) {   return x / y }

最后,script.js 文件用来确定 x 和 y 的值,以及调用前面那些函数并显示结果:

script.js

const x = 10 const y = 5  document.getElementById('x').textContent = x document.getElementById('y').textContent = y  document.getElementById('addition').textContent = sum(x, y) document.getElementById('subtraction').textContent = difference(x, y) document.getElementById('multiplication').textContent = product(x, y) document.getElementById('division').textContent = quotient(x, y)

保存之后在浏览器中打开 index.html 可以看到所有结果:

原生JavaScript中如何用关键字import和export来实现一个模块接口

对于只需要一些小脚本的网站,这不失为一种有效的组织代码的方法。但是这种方法存在一些问题:

  • 污染全局命名空间:你在脚本中创建的所有变量(sum、 difference 等)现在都存在于 window 对象中。如果你打算在另一个文件中使用另一个名为  sum 的变量,会很难知道在脚本的其它位置到底用的是哪一个值变量,因为它们用的都是相同的 window.sum  变量。唯一可以使变量私有的方法是将其放在函数的作用域中。甚至在 DOM 中名为 x 的 id 可能会和 var x 存在冲突。

  • 依赖管理:必须从上到下依次加载脚本来确保可以使用正确的变量。将脚本分别保存存为不同文件会产生分离的错觉,但本质上与放在页面中的单个   

    由于受限于 CORS 策略,必须在服务器环境中使用模块,否则会出现下面的错误:

    Access to script at 'file:///Users/your_file_path/script.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

    模块与常规脚本不一样的地方:

    • 模块不会向全局(window)作用域添加任何内容。

    • 模块始终处于严格模式。

    • 在同一文件中把同一模块加载两次不会出问题,因为模块仅执行一次

    • 模块需要服务器环境。

    模块仍然经常与打包程序(如 Webpack)一起配合使用,用来增加对浏览器的支持和附加功能,但它们也可以直接用在浏览器中。

    接下来探索更多使用 import 和 export 语法的方式。

    命名导出

    如前所述,使用 export 语法允许你分别导入按名称导出的值。以这个 function.js 的简化版本为例:

    functions.js

    export function sum() {} export function difference() {}

    这样允许你用花括号按名称导入 sum 和 difference:

    script.js

    import {sum, difference} from './functions.js'

    也可以用别名来重命名该函数。这样可以避免在同一模块中产生命名冲突。在这个例子中,sum 将重命名为 add,而 difference 将重命名为  subtract。

    script.js

    import {   sum as add,   difference as subtract } from './functions.js'  add(1, 2) // 3

    在这里调用 add() 将产生 sum() 函数的结果。

    使用 * 语法可以将整个模块的内容导入到一个对象中。在这种情况下,sum 和 difference 将成为 mathFunctions  对象上的方法。

    script.js

    import * as mathFunctions from './functions.js'  mathFunctions.sum(1, 2) // 3 mathFunctions.difference(10, 3) // 7

    原始值、函数表达式和定义、异步函数、类和实例化的类都可以导出,只要它们有标识符就行:

    // 原始值 export const number = 100 export const string = 'string' export const undef = undefined export const empty = null export const obj = {name: 'Homer'} export const array = ['Bart', 'Lisa', 'Maggie']  // 函数表达式 export const sum = (x, y) => x + y  // 函数定义 export function difference(x, y) {   return x - y }  // 匿名函数 export async function getBooks() {}  // 类 export class Book {   constructor(name, author) {     this.name = name     this.author = author   } }  // 实例化类 export const book = new Book('Lord of the Rings', 'J. R. R. Tolkein')

    所有这些导出都可以成功被导入。接下来要探讨的另一种导出类型称为默认导出。

    默认导出在前面的例子中我们导出了多个命名的导出,并分别或作为一个对象导入了每个导出,将每个导出作为对象上的方法。模块也可以用关键字 default  包含默认导出。默认导出不使用大括号导入,而是直接导入到命名标识符中。

    以 functions.js 文件为例:

    functions.js

    export default function sum(x, y) {   return x + y }

    在 script.js 文件中,可以用以下命令将默认函数导入为 sum:

    script.js

    import difference from './functions.js'  difference(1, 2) // 3

    不过这样做很危险,因为在导入过程中对默认导出的命名没有做任何限制。在这个例子中,默认函数被导入为 difference,尽管它实际上是 sum  函数:

    script.js

    import difference from './functions.js'  difference(1, 2) // 3

    所以一般首选使用命名导出。与命名导出不同,默认导出不需要标识符——原始值本身或匿名函数都可以用作默认导出。以下是用作默认导出的对象的示例:

    functions.js

    export default {   name: 'Lord of the Rings',   author: 'J. R. R. Tolkein', }

    可以用以下命令将其作为 book 导入:

    functions.js

    import book from './functions.js'

    同样,下面的例子演示了如何将匿名箭头函数导出为默认导出:

    functions.js

    export default () => 'This function is anonymous'

    可以这样导入:

    script.js

    import anonymousFunction from './functions.js'

    命名导出和默认导出可以彼此并用,例如在这个模块中,导出两个命名值和一个默认值:

    functions.js

    export const length = 10 export const width = 5  export default function perimeter(x, y) {   return 2 * (x + y) }

    可以用以下命令导入这些变量和默认函数:

    script.js

    import calculatePerimeter, {length, width} from './functions.js'  calculatePerimeter(length, width) // 30

    现在默认值和命名值都可用于脚本了。

    总结

    模块化编程设计允许我们把代码分成单个组件,这有助于代码重用,同时还可以保护全局命名空间。一个模块接口可以在原生 JavaScript 中用关键字  import 和 export 来实现。

    关于原生JavaScript中如何用关键字import和export来实现一个模块接口就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


    分享名称:原生JavaScript中如何用关键字import和export来实现一个模块接口
    分享URL:http://pwwzsj.com/article/jihhig.html