ES6中的导入/导出如何工作?

Kul*_*ear 12 javascript node.js ecmascript-6

我正在学习ES6标准,所以我从一个非常基本的示例代码开始.

我的第一个档案是 Rectangle.js

class Rectangle {
  perimeter(x, y) {
    return (2 * (x + y));
  }
  area(x, y) {
    return (x * y);
  }
}

export default class { Rectangle };
Run Code Online (Sandbox Code Playgroud)

在另一个文件中solve-1.js,我有一些像这样的导入

import Rectangle from './Rectangle';

function solveRect(l, b) {
  if (l < 0 || b < 0) {
    console.log(`Rectangle dimensions should be greater than zero:  l = ${l} and b = ${b}`);
  } else {
    console.log(Rectangle.area(l, b));
  }
}

solveRect(2, 4);
Run Code Online (Sandbox Code Playgroud)

我正在使用babel-node来运行这个程序,我确实需要安装预设,我的.babelrc包含

{
  "presets": [
    "es2015",
    "react",
    "stage-2"
  ],
  "plugins": []
}
Run Code Online (Sandbox Code Playgroud)

报告的错误信息是

/Users/Kulbear/Desktop/NodeBear/Basic/solve-1.js:13
    console.log(_Rectangle2.default.area(l, b));
                                    ^

TypeError: _Rectangle2.default.area is not a function
    at solveRect (solve-1.js:7:27)
    at Object.<anonymous> (solve-1.js:12:1)
    at Module._compile (module.js:541:32)
    at loader (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:148:5)
    at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:158:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Function.Module.runMain (module.js:575:10)
    at /usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:160:24
Run Code Online (Sandbox Code Playgroud)

编辑:

$ node --version
> v6.3.1
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 17

我看到两个问题:

  1. 这一行:

    export default class { Rectangle };
    
    Run Code Online (Sandbox Code Playgroud)

    ...试图以某种方式创建一个Rectangle.它将无法编译,但您已将第2阶段包含在您的中.babelrc,因此Babel认为这是尝试创建字段.我想你可能想要:

    export default Rectangle;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 你没有Rectangle.area(l, b).您已将其定义areaRectangle 实例的方法,而不是静态方法.将其更改为静态:

    static area() {
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    或者当您使用它时,请使用实例

    var r = new Rectangle();
    r.area(/*...*/);
    
    Run Code Online (Sandbox Code Playgroud)

    从代码中,你想要的static.

所以把这两件事放在一起(我也做了perimeter static):

Rectangle.js:

class Rectangle {
  static perimeter(x, y) {
    return (2 * (x + y));
  }
  static area(x, y) {
    return (x * y);
  }
}

export default Rectangle;
Run Code Online (Sandbox Code Playgroud)

solve-1.js:

import Rectangle from './Rectangle';

function solveRect(l, b) {
  if (l < 0 || b < 0) {
    console.log(`Rectangle dimensions should be greater than zero:  l = ${l} and b = ${b}`);
  } else {
    console.log(Rectangle.area(l, b));
  }
}
solveRect(2, 4);
Run Code Online (Sandbox Code Playgroud)

作品:

$ babel-node solve-1.js 
8

几个旁注:

  1. 如果您愿意,可以组合导出和类声明:

      export default class Rectangle {
          // ...implementaton
      }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,它是一个声明,因此与其他导出不同,它不会以;(方便的引用 ;尽管包含一个是无害的)结束.

  2. 如果Rectangle 只是static方法,没有理由为它是在所有的一类; 只使用静态函数的命名导出:

    export function perimeter {
        // ...
    }
    export function area {
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后人们导入可以使用命名导入语法,如果他们只想要其中一个:

    import area from './Rectangle';
    
    Run Code Online (Sandbox Code Playgroud)

    ...如果他们想要所有这些,他们可以使用命名空间导入:

    import * as Rectangle from './Rectangle';
    
    Run Code Online (Sandbox Code Playgroud)

    然后使用Rectangle.area或等.

    例如,它为模块的用户提供了灵活性.


Seb*_*ald 5

正如TJ已经说过的那样,以下几行并不合理:

export default class { Rectangle };
Run Code Online (Sandbox Code Playgroud)

它是有效的JS.你实际上在做的是导出一个class具有as属性的匿名,"Rectangle"并且this属性的值是你之前定义的构造函数class Rectangle.

因此,当您导入上述内容时,您必须执行以下操作才能使其正常工作:

import Rectangle from './Rectangle';

const rect1 = new Rectangle();
const rect2 = new rect1.Rectangle();
rect2.area(5,5);
Run Code Online (Sandbox Code Playgroud)

当然,这不是你想要做的.你真正想要的是:

export default Rectangle;
Run Code Online (Sandbox Code Playgroud)

此外,您似乎只想要一些方法而不是构建整个类.至少在您的示例中,您没有创建Rectangle对象的实例.

如果是这种情况,我建议您删除该类并执行以下操作:

export function perimeter (x, y) {
  return (2 * (x + y));
}
export function area(x, y) {
  return (x * y);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以执行以下操作以导入和使用已定义的方法:

import * as Rectangle from './Rectangle';
console.log(Rectangle.area(5,5));
Run Code Online (Sandbox Code Playgroud)

  • *"对我来说,无论如何,没有理智的人正在写ES5"*嗯,是的,但是`class {Rectangle; }`也不是ES2015或ES2016.这是我的观点. (2认同)