如何在Vanilla JavaScript(JS)中导入/导出类

fcy6dtqo  于 2023-04-28  发布在  Java
关注(0)|答案(4)|浏览(143)

我使用的是Vanilla JavaScript(JS)。现在,我试图利用导入/导出class和**模块 * 的概念,这是ECMA-2015(ECMA-6)版本的一部分。
请看下面的代码片段:

矩形。js:

export default class  Rectangle{
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

myHifiRectangle.js:

import Rectangle from 'rectangle.js';

class MyHiFiRectangle extends Rectangle {
  constructor(height, width) {
      super(height,width);
      this.foo= "bar";  
 }
}

我试图在一个名为test的HTML页面中引用上面提到的JS文件。html(参考代码片段):

<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title>Javascipt by Rasik Bihari Tiwari</title>
       <script src="Scripts/rectangle.js"></script>
       <script src="Scripts/myHiFiRectangle.js"></script>
      <script type="text/javascript">
    
   var v = new MyHiFiRectangle(2,4);
   console.debug(v.foo);
      </script>
   </head>
   <body >

   </body>

</html>

然后,我尝试加载test。html在浏览器中。在不同的浏览器上结果是不同的。
在Google Chrome上,我得到以下错误:
未捕获的语法错误:意外的令牌导出
在Mozilla firefox上,我得到以下错误:
语法错误:导出声明只能出现在模块的顶层
语法错误:导入声明只能出现在模块的顶层
参考错误:MyHiFiRectangle未定义[了解更多]
我尝试重新排序HTML文件的head标签中引用的JS文件,但没有影响。

注意:再次澄清,我没有使用任何像Babel这样的翻译器。我正在检查Vanilla JS中对导出/导入模块结构的本地支持以及它是如何工作的。

nkcskrwz

nkcskrwz1#

我经历了这一点,我有一个解决方案,第三个js文件作为模块。rectangle.js将是相同的,myHifiRectangle.js文件只有一个修改。

import Rectangle from './rectangle.js';

export default class MyHiFiRectangle extends Rectangle {
      constructor(height, width) {
      super(height,width);
      this.foo= "bar";  
   }
}

现在,我们需要第三个文件,它将是一个模块文件,比如script.js

import MyHiFiRectangle from './myHifiRectangle.js'

var v = new MyHiFiRectangle(2,4);
console.log(v.foo);

现在,第三个文件script.js应该成为一个模块。关于模块here的更多信息。我有所有三个文件在modelJS文件夹下。

<script type="module" src="/modelJS/script.js"></script>

现在,当您运行时,您应该看到'bar'打印在开发人员工具的控制台选项卡中。

zlhcx6iw

zlhcx6iw2#

我也在这个线程中从curiou.netter's answer得到提示后添加了一个答案。
我将以精确顺序的方式指出原始代码文件中的错误。顺便说一句,我能够解决这个问题,而不需要额外的脚本。js文件:
1.当引用JS模块时,脚本类型应该是module。我指的是myHiFiancle。js像一个普通的JS文件,使用src标记为:

src="Scripts/myHiFiRectangle.js"

我还导入了MyHiFiRectangle模块。下面是head标签在测试中的外观。html文件修复此错误后:

<head>
  <meta charset = "UTF-8">
  <title>Javascipt by Rasik Bihari Tiwari</title>
  <script type="module">
     import MyHiFiRectangle from './scripts/myHiFirectangle.js';
     var v = new MyHiFiRectangle(2,4);
     console.debug(v.foo);
  </script>
</head>

1.myHiFiRectangle中缺少export default语句。js文件。当必须从不同的地方使用时,每个类都必须导出为模块。已纠正的myHiFiRectangle。js文件如下所示:

import Rectangle from './rectangle.js';
export default class MyHiFiRectangle extends Rectangle {
  constructor(height, width) {
  super(height,width);
  this.foo= "bar";  
 }
}

1.我的脚本文件在导入模块的过程中出现了另一个错误。

错误方式:

import Rectangle from 'rectangle.js';
import MyHiFiRectangle from '/scripts/myHiFirectangle.js';

它会导致以下错误,这是不言自明的:
未捕获的类型错误:无法解析模块说明符“矩形”。js”。相对引用必须以“/"、“开头。/”,或“../”。

正确方式:

import Rectangle from './rectangle.js';
import MyHiFiRectangle from './scripts/myHiFirectangle.js';
7eumitmz

7eumitmz3#

我想向你展示一个替代解决方案,以什么@安迪盖斯凯尔张贴。
首先,你需要babel来确保你可以在浏览器中使用ES6。这是为了确保您的代码仍然可以在某些浏览器(如IE等传统浏览器)不支持现代JavaScript(ES6及更高版本)功能(如导入/导出和类)的情况下工作。
您可以添加以下脚本

`<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>`

在上面提到的任何其他JavaScript文件之前。
其次,如果你内联了你的javascript类,这些类的作用域就变成了全局的,即使它们驻留在自己的物理js文件中。
我已经包括了下面的工作示例,我已经对它做了一些修改,以便它可以在代码片段中工作。您希望用包含JavaScript文件的脚本替换该脚本,就像在代码中所做的那样。

<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title>Javascipt by Rasik Bihari Tiwari</title>
       <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

      <!-- Replace them with script with src pointing to your javascript -->       
      <script type="text/javascript"> 
        class  Rectangle{
          constructor(height, width) {
            this.height = height;
            this.width = width;
          }
        }

        class MyHiFiRectangle extends Rectangle {
          constructor(height, width) {
              super(height,width);
              this.foo= "bar";  
         }
        }
           
       var v = new MyHiFiRectangle(2,4);
       console.log(v.foo);
       </script>
   </head>
   <body >

   </body>

</html>

已更新

好的。酷!顺便说一句,如果我把所有的类定义都放到我的html页面本身的script标签中,那么我甚至不需要在head标签中引用babel-core。为什么要这么做?
对于不支持类(如IE)的浏览器,您可能需要它。但是,如果您不需要兼容传统浏览器,那么您就不需要它。
……我还需要进出口的东西吗?当每个类都或多或少是全局的时候,在原生javascript中模块导出的意义是什么?
实际上,您不需要导出-导入的东西,因为您的类是全局的。只有当您想使用模块系统时才使用此选项。如果你不使用导入/导出,你的类应该是全局的,因此应该工作。但万一它不知道怎么回事。通过将它附加到window对象,确保它全局存在,如下所示:

window.myClass = class MyClass { /* Class definition */ }
6ju8rftf

6ju8rftf4#

在大多数浏览器中,这是通过feature flag启用的。
Chrome:转到about:flags并启用“Experimental Web Platform features”。
Firefox从版本54开始:dom.moduleScripts.enabled
Edge 15或更新版本:在about:flags中启用“实验JavaScript功能”。

相关问题