Как работает импорт/экспорт в ES6?
Я изучаю стандарт ES6, поэтому я начинаю с очень простого примера кода.
Мой первый файл Rectangle.js
class Rectangle {
perimeter(x, y) {
return (2 * (x + y));
}
area(x, y) {
return (x * y);
}
}
export default class { Rectangle };
И в другом файле 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);
Я использую babel- node для запуска этой программы, у меня есть необходимые предустановки, мой .babelrc
содержит
{
"presets": [
"es2015",
"react",
"stage-2"
],
"plugins": []
}
Сообщенная информация об ошибке была
/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
Edit:
$ node --version
> v6.3.1
Ответы
Ответ 1
Я вижу две проблемы:
-
Эта строка:
export default class { Rectangle };
... пытается создать новый класс, содержащий Rectangle
. Это не скомпилировалось, но вы включили Stage 2 в свой .babelrc
, и поэтому Babel считает попыткой создать field, Я думаю, вы, вероятно, захотите:
export default Rectangle;
-
У вас нет Rectangle.area(l, b)
. Вы определили area
как метод экземпляров Rectangle
, а не как статический метод. Либо измените его на статическую:
static area() {
// ...
}
или, когда вы используете его, используйте экземпляр
var r = new Rectangle();
r.area(/*...*/);
Из кода вы хотите 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;
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);
Работает:
$ babel-node solve-1.js
8
Несколько примечаний:
-
Если вам нравится, вы можете объединить декларацию экспорта и класса:
export default class Rectangle {
// ...implementaton
}
Обратите внимание, что это декларация, так что в отличие от других экспонатов, она не заканчивается ;
(полезной ссылкой, хотя включение одного из них безвредны).
-
Если Rectangle
имеет только методы static
, нет никаких оснований для того, чтобы он был классом вообще; просто используйте именованный экспорт ваших статических функций:
export function perimeter {
// ...
}
export function area {
// ...
}
Затем люди, импортирующие, могут использовать именованный синтаксис import, если они просто хотят одного из них:
import area from './Rectangle';
... и если они хотят все из них, они могут использовать импорт пространства имен:
import * as Rectangle from './Rectangle';
а затем используйте Rectangle.area
или такой.
Например, он предоставляет пользователю гибкость модуля.
Ответ 2
Как T.J. уже сказано, следующая строка не имеет смысла:
export default class { Rectangle };
Но допустимо JS. Фактически вы делаете экспорт анонимного class
, который имеет свойство "Rectangle"
, а значение этого свойства является конструктором для вашего ранее определенного class Rectangle
.
Поэтому, когда вы импортируете вышеуказанное, вам нужно будет сделать следующее, чтобы он работал правильно:
import Rectangle from './Rectangle';
const rect1 = new Rectangle();
const rect2 = new rect1.Rectangle();
rect2.area(5,5);
Конечно, это не то, что вы хотели сделать. Вы действительно хотите:
export default Rectangle;
Кроме того, кажется, что вам просто нужны некоторые методы, а не целостный класс. По крайней мере, в вашем примере вы не создаете экземпляр объекта Rectangle
.
Если это так, я бы предложил вам удалить класс и сделать что-то вроде этого:
export function perimeter (x, y) {
return (2 * (x + y));
}
export function area(x, y) {
return (x * y);
}
Затем вы можете сделать следующее для импорта и использования определенных методов:
import * as Rectangle from './Rectangle';
console.log(Rectangle.area(5,5));