<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          JS 中的require 和 import 區別

          時間:?2017-11-22閱讀:?2436標簽:?es6
          簡介

          遵循的模塊化規范不一樣

          模塊化規范:即為 JavaScript 提供一種模塊編寫、模塊依賴和模塊運行的方案。誰讓最初的 JavaScript 是那么的裸奔呢——全局變量就是它的模塊化規范。

          require/exports 出生在野生規范當中,什么叫做野生規范?即這些規范是 JavaScript 社區中的開發者自己草擬的規則,得到了大家的承認或者廣泛的應用。比如 CommonJS、AMD、CMD 等等。import/export 則是名門正派。TC39 制定的新的 ECMAScript 版本,即 ES6(ES2015)中包含進來。

          出現的時間不同

          require/exports 相關的規范由于野生性質,在 2010 年前后出生。AMD、CMD 相對命比較短,到 2014 年基本上就搖搖欲墜了。一開始大家還比較喜歡在瀏覽器上采用這種異步小模塊的加載方式,但并不是銀彈。隨著 Node.js 流行和 Browsersify 的興起,運行時異步加載逐漸被構建時模塊合并分塊所替代。Wrapper 函數再也不需要了。 2014 年 Webpack 還是新玩意,現在已經是前端必備神器了。


          具體區別


          1.ES6 模塊的設計思想,是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。

          Require是CommonJS的語法,CommonJS的模塊是對象,輸入時必須查找對象屬性。

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

          above:整體加載fs模塊(即加載fs所有方法),生成一個對象"_fs",然后再從這個對象上讀取三個方法,這叫“運行時加載”,因為只有運行時才能得到這個對象,不能在編譯時做到靜態化。

          ES6模塊不是對象,而是通過export命令顯示指定輸出代碼,再通過import輸入。

          import { stat, exists, readFile } from 'fs';

          above:從fs加載“stat, exists, readFile” 三個方法,其他方法不加載,


          2.ES6模塊默認使用嚴格模式,無論是否聲明“use strict”

          ES6 模塊之中,頂層的this指向undefined,即不應該在頂層代碼使用this。

          Module 主要由兩個命令組成,import和export,export用于規定模塊的對外接口,import命令用于輸入其他模塊提供的功能


          3.Export

          模塊是獨立的文件,該文件內部的所有的變量外部都無法獲取。如果希望獲取某個變量,必須通過export輸出,

          // profile.js
          export var firstName = 'Michael';
          export var lastName = 'Jackson';
          export var year = 1958;

          或者用更好的方式:用大括號指定要輸出的一組變量

          // profile.js
          var firstName = 'Michael';
          var lastName = 'Jackson';
          var year = 1958;
          
          export {firstName, lastName, year};

          除了輸出變量,還可以輸出函數或者類(class),

          export function multiply(x, y) {
            return x * y;
          };

          還可以批量輸出,同樣是要包含在大括號里,也可以用as重命名:

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

          Attention:export 命令規定的是對外接口,必須與模塊內部變量建立一一對應的關系

          // 寫法一
          export var m = 1;
          
          // 寫法二
          var m = 1;
          export {m};
          
          // 寫法三
          var n = 1;
          export {n as m};
          
          // 報錯
          export 1;
          
          // 報錯
          var m = 1;
          export m;

          報錯的寫法原因是:沒有提供對外的接口,第一種直接輸出1,第二種雖然有變量m,但還是直接輸出1,導致無法解構。

          同樣的,function和class的輸出,也必須遵守這樣的寫法。

          // 報錯
          function f() {}
          export f;
          
          // 正確
          export function f() {};
          
          // 正確
          function f() {}
          export {f};

           

          And:export語句輸出的接口,都是和其對應的值是動態綁定的關系,即通過該接口取到的都是模塊內部實時的值。

          位置:export模塊可以位于模塊中的任何位置,但是必須是在模塊頂層,如果在其他作用域內,會報錯。

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


          4.Import命令

          export定義了模塊的對外接口后,其他JS文件就可以通過import來加載這個模塊,

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

          import命令接受一對大括號,里面指定要從其他模塊導入的變量名,

          必須與被導入模塊(profile.js)對外接口的名稱相同

          如果想重新給導入的變量一個名字,可以用as關鍵字,

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

          import后的from 可以指定需要導入模塊的路徑名,可以是絕對路徑,也可以是相對路徑, .js路徑可以省略,如果只有模塊名,不帶有路徑,需要有配置文件指定。

          注意,import命令具有提升效果,會提升到整個模塊的頭部,首先執行。(是在編譯階段執行的)

          因為import是靜態執行的,不能使用表達式和變量,即在運行時才能拿到結果的語法結構(e.g. if...else...)


          5.module的整體加載

          除了指定加載某個輸出值,還可以用(*)指定一個對象,所有的變量都會加載在這個對象上。

          // circle.js。輸出兩個函數
          
          export function area(radius) {
            return Math.PI * radius * radius;
          }
          
          export function circumference(radius) {
            return 2 * Math.PI * radius;
          }
          
          
          // main.js 加載在個模塊
          import { area, circumference } from './circle';
          
          console.log('圓面積:' + area(4));
          console.log('圓周長:' + circumference(14));
          
          //上面寫法是逐一指定要加載的方法,整體加載的寫法如下。
          import * as circle from './circle';
          
          console.log('圓面積:' + circle.area(4));
          console.log('圓周長:' + circle.circumference(14));

          注意,模塊整體加載所在的那個對象(上例是circle),應該是可以靜態分析的,所以不允許運行時改變。

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


          6.export default

          之前的例子中,使用import導入時,都需要知道模塊中所要加載的變量名或函數名,用戶可能不想閱讀源碼,只想直接使用接口,就可以用export default命令,為模塊指定輸出

          // export-default.js
          export default function () {
            console.log('foo');
          }

          其他模塊加載該模塊時,import命令可以為該匿名函數指定任意名字。

          // import-default.js
          import customName from './export-default';
          customName(); // 'foo'

          export default也可以用于非匿名函數前。

          下面比較一下默認輸出和正常輸出。

          // 第一組
          export default function crc32() { // 輸出
            // ...
          }
          
          import crc32 from 'crc32'; // 輸入
          
          // 第二組
          export function crc32() { // 輸出
            // ...
          };
          
          import {crc32} from 'crc32'; // 輸入

          可以看出,使用export default時,import語句不用使用大括號。

           

          *******import和export命令只能在模塊的頂層,不能在代碼塊之中。否則會語法報錯。

          這樣的設計,可以提高編譯器效率,但是沒有辦法實現運行時加載。

          因為require是運行時加載,所以import命令沒有辦法代替require的動態加載功能。

          所以引入了import()函數。完成動態加載。

          import(specifier)

          specifier用來指定所要加載的模塊的位置。import能接受什么參數,import()可以接受同樣的參數。

          import()返回一個Promise對象。

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


          7.import()函數適用場合

           1)按需加載:

          button.addEventListener('click', event => {
            import('./dialogBox.js')
            .then(dialogBox => {
              dialogBox.open();
            })
            .catch(error => {
              /* Error handling */
            })
          });

          above: import模塊在事件監聽函數中,只有用戶點擊了按鈕,才會加載這個模塊。

           2)條件加載:

          import()可以放在if...else語句中,實現條件加載。

          if (condition) {
            import('moduleA').then(...);
          } else {
            import('moduleB').then(...);
          }

           

          ---摘自阮大神的 ES6, 僅供自己記錄參考。


          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/148

          ES6 Iterators

          本文旨在分析理解 Iterators。 Iterators 是 JS中的新方法,可以用來循環任意集合。 在ES6中登場的Iterators。因其可被廣泛使用,并且已在多處場景派上用場,

          24個常用的es6方法

          本文主要介紹 24 中 es6 方法,這些方法都挺實用的,本本請記好,時不時翻出來看看。如何檢查元素是否具有指定的類?頁面DOM里的每個節點上都有一個classList對象,程序員可以使用里面的方法新增、刪除、修改節點上的CSS類。

          javascript es6是什么?

          ES6就是ECMAScript6是新版本JavaScript語言的標準。已經在2015年6月正式發布了。Mozilla公司將在這個標準的基礎上,推出JavaScript 2.0。ECMAScript6在保證向下兼容的前提下

          ES6 Promise用法詳解

          Promise是一個構造函數,接受一個參數(Function),并且該參數接受兩個參數resolve和reject(分別表示異步操作執行成功后的回調函數、執行失敗后的回調函數)

          commonjs 與 es6相關Module語法的區別

          export 在接口名字與模塊內部的變量之間建立了一一對應的關系,export輸出的接口; export的寫法,除了像上面這樣,還有另外一種。export命令除了輸出變量,還可以輸出函數或類(class)。

          ES6箭頭函數(Arrow Functions)

          箭頭函數中的 this 指向的是定義時的對象,而不是使用時的對象;由于 箭頭函數沒有自己的this指針,通過 call() 或 apply() 方法調用一個函數時,只能傳遞參數,他們的第一個參數會被忽略

          es6 class

          構造函數的prototype屬性,在 ES6 的“類”上面繼續存在。事實上,類的所有方法都定義在類的prototype屬性上面。

          es6之迭代器

          迭代器是被設計專用于迭代的對象,帶有特定接口。所有的迭代器對象都擁有 next() 方法,會返回一個結果對象。該結果對象有兩個屬性:對應下一個值的 value ,以及一個布爾類型的 done

          ES6 - let、const、var的區別

          為了使JavaScript語言可以用來編寫復雜的大型應用程序,成為企業級開發語言,ECMAScript 6.0(簡稱ES6)在標準中添加了很多新的特性。我們將用幾篇文章總結一下ES6標準中一些常用的新特性。本片文章主要講解ES6中的let、const命令,并區分其與var命令的區別。

          ES6新的變量聲明方式

          在ES6之前,JavaScript是沒有塊級作用域的,如果在塊內使用var聲明一個變量,它在代碼塊外面仍舊是可見的。ES6規范給開發者帶來了塊級作用域,let和const都添加了塊級作用域,使得JS更嚴謹和規范。

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网