この章では、ES6 の主要な機能について説明します。これらの機能は簡単に採用できます。残りの機能は主にライブラリ作成者にとって興味深いものです。各機能について、対応する ES5 コードを使って説明します。
var
から const
/let
へfor
から forEach()
、そして for-of
へarguments
からレストパラメータへapply()
からスプレッド演算子 (...
) へMath.max()
Array.prototype.push()
concat()
からスプレッド演算子 (...
) へError
のサブクラスへArray.prototype.indexOf
から Array.prototype.findIndex
へArray.prototype.slice()
から Array.from()
またはスプレッド演算子へapply()
から Array.prototype.fill()
へvar
から const
/let
へ ES5 では、var
を使って変数を宣言します。このような変数は *関数スコープ* であり、そのスコープは最も内側の囲み関数です。var
の動作は時に紛らわしいことがあります。次に例を示します。
var
x
=
3
;
function
func
(
randomize
)
{
if
(
randomize
)
{
var
x
=
Math
.
random
();
// (A) scope: whole function
return
x
;
}
return
x
;
// accesses the x from line A
}
func
(
false
);
// undefined
func()
が undefined
を返すのは驚きかもしれません。実際に何が起こっているかをより正確に反映するようにコードを書き換えると、その理由がわかります。
var
x
=
3
;
function
func
(
randomize
)
{
var
x
;
if
(
randomize
)
{
x
=
Math
.
random
();
return
x
;
}
return
x
;
}
func
(
false
);
// undefined
ES6 では、追加で let
および const
を使用して変数を宣言できます。このような変数は *ブロックスコープ* であり、そのスコープは最も内側の囲みブロックです。let
は、おおまかに言えば var
のブロックスコープ版です。const
は let
と同様に機能しますが、値を変更できない変数を作成します。
let
と const
はより厳密に動作し、より多くの例外をスローします(例:宣言される前にスコープ内で変数にアクセスした場合)。ブロックスコープは、コードフラグメントの効果をより局所的に保つのに役立ちます(デモについては次のセクションを参照)。また、関数スコープよりも主流であり、JavaScript と他のプログラミング言語間の移動が容易になります。
最初のバージョンで var
を let
に置き換えると、異なる動作になります。
let
x
=
3
;
function
func
(
randomize
)
{
if
(
randomize
)
{
let
x
=
Math
.
random
();
return
x
;
}
return
x
;
}
func
(
false
);
// 3
つまり、既存のコードで var
を let
または const
で盲目的に置き換えることはできません。リファクタリング中は注意が必要です。
私のアドバイスは以下のとおりです。
const
を優先します。値が変更されないすべての変数に使用できます。let
を使用します。var
は避けてください。詳細情報: “変数とスコープ” の章。
ES5 では、変数 tmp
のスコープをブロックに制限したい場合は、IIFE (即時実行関数式) と呼ばれるパターンを使用する必要がありました。
(
function
()
{
// open IIFE
var
tmp
=
···
;
···
}());
// close IIFE
console
.
log
(
tmp
);
// ReferenceError
ECMAScript 6 では、ブロックと let
宣言 (または const
宣言) を使用するだけで済みます。
{
// open block
let
tmp
=
···
;
···
}
// close block
console
.
log
(
tmp
);
// ReferenceError
詳細情報: “ES6 で IIFE を避ける” のセクション。
ES6 では、JavaScript に文字列補間と複数行文字列のリテラルがついに導入されました。
ES5 では、文字列に値を入れるには、それらの値と文字列フラグメントを連結します。
function
printCoord
(
x
,
y
)
{
console
.
log
(
'('
+
x
+
', '
+
y
+
')'
);
}
ES6 では、テンプレートリテラルによる文字列補間を使用できます。
function
printCoord
(
x
,
y
)
{
console
.
log
(
`(
${
x
}
,
${
y
}
)`
);
}
テンプレートリテラルは、複数行文字列の表現にも役立ちます。
たとえば、ES5 でそれを表現するには、次のようにする必要があります。
var
HTML5_SKELETON
=
'<!doctype html>\n'
+
'<html>\n'
+
'<head>\n'
+
' <meta charset="UTF-8">\n'
+
' <title></title>\n'
+
'</head>\n'
+
'<body>\n'
+
'</body>\n'
+
'</html>\n'
;
バックスラッシュを使って改行をエスケープすると、少し見栄えが良くなります(ただし、明示的に改行を追加する必要があります)。
var
HTML5_SKELETON
=
'\
<!doctype html>\n\
<html>\n\
<head>\n\
<meta charset="UTF-8">\n\
<title></title>\n\
</head>\n\
<body>\n\
</body>\n\
</html>'
;
ES6 のテンプレートリテラルは複数行にまたがることができます。
const
HTML5_SKELETON
=
`
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
</html>`
;
(例では、含まれる空白の量が異なりますが、この場合は問題ありません。)
詳細情報: “テンプレートリテラルとタグ付きテンプレート” の章。
現在の ES5 コードでは、関数式を使用している場合は常に、this
に注意する必要があります。次の例では、UiComponent
の this
が B 行でアクセスできるように、ヘルパー変数 _this
(A 行) を作成します。
function
UiComponent
()
{
var
_this
=
this
;
// (A)
var
button
=
document
.
getElementById
(
'myButton'
);
button
.
addEventListener
(
'click'
,
function
()
{
console
.
log
(
'CLICK'
);
_this
.
handleClick
();
// (B)
});
}
UiComponent
.
prototype
.
handleClick
=
function
()
{
···
};
ES6 では、this
をシャドウしないアロー関数を使用できます (A 行)。
function
UiComponent
()
{
var
button
=
document
.
getElementById
(
'myButton'
);
button
.
addEventListener
(
'click'
,
()
=>
{
console
.
log
(
'CLICK'
);
this
.
handleClick
();
// (A)
});
}
(ES6 では、コンストラクタ関数の代わりにクラスを使用することもできます。これについては後で説明します。)
アロー関数は、式の結果のみを返す短いコールバックに特に便利です。
ES5 では、このようなコールバックは比較的冗長です。
var
arr
=
[
1
,
2
,
3
];
var
squares
=
arr
.
map
(
function
(
x
)
{
return
x
*
x
});
ES6 では、アロー関数ははるかに簡潔です。
const
arr
=
[
1
,
2
,
3
];
const
squares
=
arr
.
map
(
x
=>
x
*
x
);
パラメータを定義するとき、パラメータが単一の識別子である場合は、括弧を省略することもできます。したがって、(x) => x * x
と x => x * x
はどちらも許可されます。
詳細情報: “アロー関数” の章。
一部の関数またはメソッドは、配列またはオブジェクトを介して複数の値を返します。ES5 では、これらの値にアクセスする場合は常に、中間変数を作成する必要があります。ES6 では、分割代入によって中間変数を回避できます。
exec()
は、Array のようなオブジェクトを介してキャプチャされたグループを返します。ES5 では、グループのみに関心がある場合でも、中間変数 (以下の例では matchObj
) が必要です。
var
matchObj
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
'2999-12-31'
);
var
year
=
matchObj
[
1
];
var
month
=
matchObj
[
2
];
var
day
=
matchObj
[
3
];
ES6 では、分割代入によってこのコードが簡略化されます。
const
[,
year
,
month
,
day
]
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
'2999-12-31'
);
配列パターンの先頭にある空のスロットは、インデックス 0 の配列要素をスキップします。
メソッド Object.getOwnPropertyDescriptor()
は、*プロパティ記述子* (プロパティに複数の値を保持するオブジェクト) を返します。
ES5 では、オブジェクトのプロパティのみに関心がある場合でも、中間変数 (以下の例では propDesc
) が必要です。
var
obj
=
{
foo
:
123
};
var
propDesc
=
Object
.
getOwnPropertyDescriptor
(
obj
,
'foo'
);
var
writable
=
propDesc
.
writable
;
var
configurable
=
propDesc
.
configurable
;
console
.
log
(
writable
,
configurable
);
// true true
ES6 では、分割代入を使用できます。
const
obj
=
{
foo
:
123
};
const
{
writable
,
configurable
}
=
Object
.
getOwnPropertyDescriptor
(
obj
,
'foo'
);
console
.
log
(
writable
,
configurable
);
// true true
{writable, configurable}
は、
{
writable
:
writable
,
configurable
:
configurable
}
詳細情報: “分割代入” の章。
for
から forEach()
、そして for-of
へ ES5 以前は、次のように配列を反復処理しました。
var
arr
=
[
'a'
,
'b'
,
'c'
];
for
(
var
i
=
0
;
i
<
arr
.
length
;
i
++
)
{
var
elem
=
arr
[
i
];
console
.
log
(
elem
);
}
ES5 では、Array メソッド forEach()
を使用できます。
arr
.
forEach
(
function
(
elem
)
{
console
.
log
(
elem
);
});
for
ループには、そこから中断できるという利点があり、forEach()
には簡潔さという利点があります。
ES6 では、for-of
ループが両方の利点を兼ね備えています。
const
arr
=
[
'a'
,
'b'
,
'c'
];
for
(
const
elem
of
arr
)
{
console
.
log
(
elem
);
}
各配列要素のインデックスと値の両方が必要な場合、for-of
は、新しい Array メソッド entries()
と分割代入を介して、それらにも対応できます。
for
(
const
[
index
,
elem
]
of
arr
.
entries
())
{
console
.
log
(
index
+
'. '
+
elem
);
}
詳細情報: “for-of
ループ” の章。
ES5 では、次のようにパラメータのデフォルト値を指定します。
function
foo
(
x
,
y
)
{
x
=
x
||
0
;
y
=
y
||
0
;
···
}
ES6 には、より優れた構文があります。
function
foo
(
x
=
0
,
y
=
0
)
{
···
}
追加の利点は、ES6 では、パラメータのデフォルト値は undefined
によってのみトリガーされるのに対し、以前の ES5 コードでは任意の偽の値によってトリガーされることです。
詳細情報: “パラメータのデフォルト値” のセクション。
JavaScript でパラメータに名前を付ける一般的な方法は、オブジェクトリテラル (いわゆる *オプションオブジェクトパターン*) を使用することです。
selectEntries
({
start
:
0
,
end
:
-
1
});
このアプローチの 2 つの利点は、コードがより自己記述的になることと、任意のパラメータを省略するのが簡単になることです。
ES5 では、selectEntries()
を次のように実装できます。
function
selectEntries
(
options
)
{
var
start
=
options
.
start
||
0
;
var
end
=
options
.
end
||
-
1
;
var
step
=
options
.
step
||
1
;
···
}
ES6 では、パラメータ定義で分割代入を使用でき、コードが簡略化されます。
function
selectEntries
({
start
=
0
,
end
=-
1
,
step
=
1
})
{
···
}
ES5 でパラメータ options
をオプションにするには、A 行をコードに追加します。
function
selectEntries
(
options
)
{
options
=
options
||
{};
// (A)
var
start
=
options
.
start
||
0
;
var
end
=
options
.
end
||
-
1
;
var
step
=
options
.
step
||
1
;
···
}
ES6 では、{}
をパラメータのデフォルト値として指定できます。
function
selectEntries
({
start
=
0
,
end
=-
1
,
step
=
1
}
=
{})
{
···
}
詳細情報: “名前付きパラメータのシミュレーション” のセクション。
arguments
からレストパラメータへ ES5 では、関数 (またはメソッド) で任意の数の引数を受け入れるようにする場合は、特殊な変数 arguments
を使用する必要があります。
function
logAllArguments
()
{
for
(
var
i
=
0
;
i
<
arguments
.
length
;
i
++
)
{
console
.
log
(
arguments
[
i
]);
}
}
ES6 では、...
演算子を使用して、レストパラメータ (以下の例では args
) を宣言できます。
function
logAllArguments
(...
args
)
{
for
(
const
arg
of
args
)
{
console
.
log
(
arg
);
}
}
末尾のパラメータのみに関心がある場合、レストパラメータはさらに優れています。
function
format
(
pattern
,
...
args
)
{
···
}
ES5 でこのケースを処理するのは面倒です。
function
format
(
pattern
)
{
var
args
=
[].
slice
.
call
(
arguments
,
1
);
···
}
レストパラメータを使用すると、コードが読みやすくなります。パラメータ定義を見るだけで、関数に可変数のパラメータがあることがわかります。
詳細情報: “レストパラメータ” のセクション。
apply()
からスプレッド演算子 (...
) へ ES5 では、apply()
を使用して配列をパラメータに変換します。ES6 には、この目的のためのスプレッド演算子があります。
Math.max()
Math.max()
は、その引数の中で数値的に最大なものを返します。任意の数の引数に対して機能しますが、配列に対しては機能しません。
ES5 – apply()
> Math.max.apply(Math, [-1, 5, 11, 3])
11
ES6 – スプレッド演算子
> Math.max(...[-1, 5, 11, 3])
11
Array.prototype.push()
Array.prototype.push()
は、その引数をすべて要素としてレシーバーに追加します。配列を別の配列に破壊的に追加するメソッドはありません。
ES5 – apply()
var
arr1
=
[
'a'
,
'b'
];
var
arr2
=
[
'c'
,
'd'
];
arr1
.
push
.
apply
(
arr1
,
arr2
);
// arr1 is now ['a', 'b', 'c', 'd']
ES6 – スプレッド演算子
const
arr1
=
[
'a'
,
'b'
];
const
arr2
=
[
'c'
,
'd'
];
arr1
.
push
(...
arr2
);
// arr1 is now ['a', 'b', 'c', 'd']
詳細情報: 「スプレッド演算子 (...
)」のセクションを参照してください。
concat()
からスプレッド演算子 (...
) へ スプレッド演算子は、(非破壊的に)オペランドの内容を配列要素に変換することもできます。つまり、配列メソッド concat()
の代替となります。
ES5 – concat()
var
arr1
=
[
'a'
,
'b'
];
var
arr2
=
[
'c'
];
var
arr3
=
[
'd'
,
'e'
];
console
.
log
(
arr1
.
concat
(
arr2
,
arr3
));
// [ 'a', 'b', 'c', 'd', 'e' ]
ES6 – スプレッド演算子
const
arr1
=
[
'a'
,
'b'
];
const
arr2
=
[
'c'
];
const
arr3
=
[
'd'
,
'e'
];
console
.
log
([...
arr1
,
...
arr2
,
...
arr3
]);
// [ 'a', 'b', 'c', 'd', 'e' ]
詳細情報: 「スプレッド演算子 (...
)」のセクションを参照してください。
JavaScript では、メソッドは値が関数であるプロパティです。
ES5 のオブジェクトリテラルでは、メソッドは他のプロパティと同様に作成されます。プロパティの値は、関数式を介して提供されます。
var
obj
=
{
foo
:
function
()
{
···
},
bar
:
function
()
{
this
.
foo
();
},
// trailing comma is legal in ES5
}
ES6 には、メソッドを作成するための特別な構文であるメソッド定義があります。
const
obj
=
{
foo
()
{
···
},
bar
()
{
this
.
foo
();
},
}
詳細情報: 「メソッド定義」のセクションを参照してください。
ES6 のクラスは、ほとんどがコンストラクター関数に対するより便利な構文にすぎません。
ES5 では、コンストラクター関数を直接実装します。
function
Person
(
name
)
{
this
.
name
=
name
;
}
Person
.
prototype
.
describe
=
function
()
{
return
'Person called '
+
this
.
name
;
};
ES6 では、クラスはコンストラクター関数に対するわずかに便利な構文を提供します。
class
Person
{
constructor
(
name
)
{
this
.
name
=
name
;
}
describe
()
{
return
'Person called '
+
this
.
name
;
}
}
メソッド定義のコンパクトな構文に注目してください。キーワード function
は不要です。また、クラスの各部分の間にカンマがないことにも注意してください。
ES5 では、特にスーパークラスのコンストラクターやスーパープロパティを参照する場合、サブクラス化は複雑です。以下は、Person
のサブコンストラクター Employee
を作成するための標準的な方法です。
function
Employee
(
name
,
title
)
{
Person
.
call
(
this
,
name
);
// super(name)
this
.
title
=
title
;
}
Employee
.
prototype
=
Object
.
create
(
Person
.
prototype
);
Employee
.
prototype
.
constructor
=
Employee
;
Employee
.
prototype
.
describe
=
function
()
{
return
Person
.
prototype
.
describe
.
call
(
this
)
// super.describe()
+
' ('
+
this
.
title
+
')'
;
};
ES6 には、extends
句を介したサブクラス化の組み込みサポートがあります。
class
Employee
extends
Person
{
constructor
(
name
,
title
)
{
super
(
name
);
this
.
title
=
title
;
}
describe
()
{
return
super
.
describe
()
+
' ('
+
this
.
title
+
')'
;
}
}
詳細情報: 「クラス」の章を参照してください。
Error
のサブクラスへ ES5 では、例外のための組み込みコンストラクターである Error
をサブクラス化することは不可能です。次のコードは、MyError
コンストラクターにスタックトレースなどの重要な機能を与えるための回避策を示しています。
function
MyError
()
{
// Use Error as a function
var
superInstance
=
Error
.
apply
(
null
,
arguments
);
copyOwnPropertiesFrom
(
this
,
superInstance
);
}
MyError
.
prototype
=
Object
.
create
(
Error
.
prototype
);
MyError
.
prototype
.
constructor
=
MyError
;
function
copyOwnPropertiesFrom
(
target
,
source
)
{
Object
.
getOwnPropertyNames
(
source
)
.
forEach
(
function
(
propKey
)
{
var
desc
=
Object
.
getOwnPropertyDescriptor
(
source
,
propKey
);
Object
.
defineProperty
(
target
,
propKey
,
desc
);
});
return
target
;
};
ES6 では、すべての組み込みコンストラクターをサブクラス化できます。そのため、次のコードは ES5 のコードがシミュレートするしかないことを実現できます。
class
MyError
extends
Error
{
}
詳細情報: 「組み込みコンストラクターのサブクラス化」のセクションを参照してください。
文字列から任意の値を対応付けるマップ(データ構造)として言語構造であるオブジェクトを使用することは、JavaScript では常に一時的な解決策でした。これを行う最も安全な方法は、プロトタイプが null
のオブジェクトを作成することです。それでも、キーが文字列 '__proto__'
にならないようにする必要があります。これは、そのプロパティキーが多くの JavaScript エンジンで特別な機能をトリガーするためです。
次の ES5 コードには、オブジェクト dict
をマップとして使用する関数 countWords
が含まれています。
var
dict
=
Object
.
create
(
null
);
function
countWords
(
word
)
{
var
escapedWord
=
escapeKey
(
word
);
if
(
escapedWord
in
dict
)
{
dict
[
escapedWord
]
++
;
}
else
{
dict
[
escapedWord
]
=
1
;
}
}
function
escapeKey
(
key
)
{
if
(
key
.
indexOf
(
'__proto__'
)
===
0
)
{
return
key
+
'%'
;
}
else
{
return
key
;
}
}
ES6 では、組み込みデータ構造 Map
を使用でき、キーをエスケープする必要はありません。欠点として、Map 内の値を増分するのはあまり便利ではありません。
const
map
=
new
Map
();
function
countWords
(
word
)
{
const
count
=
map
.
get
(
word
)
||
0
;
map
.
set
(
word
,
count
+
1
);
}
Map のもう 1 つの利点は、文字列だけでなく任意の値をキーとして使用できることです。
詳細情報
ECMAScript 6 標準ライブラリは、文字列に対していくつかの新しいメソッドを提供します。
indexOf
から startsWith
へ
if
(
str
.
indexOf
(
'x'
)
===
0
)
{}
// ES5
if
(
str
.
startsWith
(
'x'
))
{}
// ES6
indexOf
から endsWith
へ
function
endsWith
(
str
,
suffix
)
{
// ES5
var
index
=
str
.
indexOf
(
suffix
);
return
index
>=
0
&&
index
===
str
.
length
-
suffix
.
length
;
}
str
.
endsWith
(
suffix
);
// ES6
indexOf
から includes
へ
if
(
str
.
indexOf
(
'x'
)
>=
0
)
{}
// ES5
if
(
str
.
includes
(
'x'
))
{}
// ES6
join
から repeat
へ (文字列を繰り返す ES5 の方法は、ハックのようなものです)
new
Array
(
3
+
1
).
join
(
'#'
)
// ES5
'#'
.
repeat
(
3
)
// ES6
詳細情報: 「新しい文字列機能」の章
ES6 には、いくつかの新しい配列メソッドもあります。
Array.prototype.indexOf
から Array.prototype.findIndex
へ 後者は NaN
を見つけるために使用できますが、前者は検出できません。
const
arr
=
[
'a'
,
NaN
];
arr
.
indexOf
(
NaN
);
// -1
arr
.
findIndex
(
x
=>
Number
.
isNaN
(
x
));
// 1
ちなみに、新しい Number.isNaN()
は、NaN
を検出するための安全な方法を提供します (非数値を数値に強制変換しないため)。
> isNaN('abc')
true
> Number.isNaN('abc')
false
Array.prototype.slice()
から Array.from()
またはスプレッド演算子へ ES5 では、Array.prototype.slice()
は配列のようなオブジェクトを配列に変換するために使用されていました。ES6 では、Array.from()
があります。
var
arr1
=
Array
.
prototype
.
slice
.
call
(
arguments
);
// ES5
const
arr2
=
Array
.
from
(
arguments
);
// ES6
値がiterableの場合(すべての配列のような DOM データ構造が現在そうであるように)、スプレッド演算子 (...
) を使用して配列に変換することもできます。
const
arr1
=
[...
'abc'
];
// ['a', 'b', 'c']
const
arr2
=
[...
new
Set
().
add
(
'a'
).
add
(
'b'
)];
// ['a', 'b']
apply()
から Array.prototype.fill()
へ ES5 では、apply()
をハックとして使用して、undefined
で埋められた任意の長さの配列を作成できます。
// Same as Array(undefined, undefined)
var
arr1
=
Array
.
apply
(
null
,
new
Array
(
2
));
// [undefined, undefined]
ES6 では、fill()
がより簡単な代替手段です。
const
arr2
=
new
Array
(
2
).
fill
(
undefined
);
// [undefined, undefined]
任意の値を埋め込んだ配列を作成する場合は、fill()
の方がさらに便利です。
// ES5
var
arr3
=
Array
.
apply
(
null
,
new
Array
(
2
))
.
map
(
function
(
x
)
{
return
'x'
});
// ['x', 'x']
// ES6
const
arr4
=
new
Array
(
2
).
fill
(
'x'
);
// ['x', 'x']
fill()
は、すべての配列要素を与えられた値に置き換えます。穴は要素であるかのように扱われます。
詳細情報: 「値で埋められた配列の作成」のセクション
ES5 でさえ、AMD 構文または CommonJS 構文に基づくモジュールシステムは、公開モジュールパターンなどの手書きのソリューションをほとんど置き換えています。
ES6 にはモジュールの組み込みサポートがあります。残念ながら、JavaScript エンジンはまだネイティブにサポートしていません。しかし、browserify、webpack、jspm などのツールを使用すると、ES6 構文を使用してモジュールを作成できるため、記述するコードは将来も使用できます。
CommonJS では、複数のエンティティを次のようにエクスポートします。
//------ lib.js ------
var
sqrt
=
Math
.
sqrt
;
function
square
(
x
)
{
return
x
*
x
;
}
function
diag
(
x
,
y
)
{
return
sqrt
(
square
(
x
)
+
square
(
y
));
}
module
.
exports
=
{
sqrt
:
sqrt
,
square
:
square
,
diag
:
diag
,
};
//------ main1.js ------
var
square
=
require
(
'lib'
).
square
;
var
diag
=
require
(
'lib'
).
diag
;
console
.
log
(
square
(
11
));
// 121
console
.
log
(
diag
(
4
,
3
));
// 5
または、モジュール全体をオブジェクトとしてインポートし、それを通して square
と diag
にアクセスすることもできます。
//------ main2.js ------
var
lib
=
require
(
'lib'
);
console
.
log
(
lib
.
square
(
11
));
// 121
console
.
log
(
lib
.
diag
(
4
,
3
));
// 5
ES6 では、複数のエクスポートは名前付きエクスポートと呼ばれ、次のように処理されます。
//------ lib.js ------
export
const
sqrt
=
Math
.
sqrt
;
export
function
square
(
x
)
{
return
x
*
x
;
}
export
function
diag
(
x
,
y
)
{
return
sqrt
(
square
(
x
)
+
square
(
y
));
}
//------ main1.js ------
import
{
square
,
diag
}
from
'lib'
;
console
.
log
(
square
(
11
));
// 121
console
.
log
(
diag
(
4
,
3
));
// 5
モジュールをオブジェクトとしてインポートするための構文は次のようになります (A 行)。
//------ main2.js ------
import
*
as
lib
from
'lib'
;
// (A)
console
.
log
(
lib
.
square
(
11
));
// 121
console
.
log
(
lib
.
diag
(
4
,
3
));
// 5
Node.js は CommonJS を拡張し、module.exports
を介してモジュールから単一の値をエクスポートできます。
//------ myFunc.js ------
module
.
exports
=
function
()
{
···
};
//------ main1.js ------
var
myFunc
=
require
(
'myFunc'
);
myFunc
();
ES6 では、同じことがいわゆるデフォルトエクスポート(export default
を介して宣言) を介して行われます。
//------ myFunc.js ------
export
default
function
()
{
···
}
// no semicolon!
//------ main1.js ------
import
myFunc
from
'myFunc'
;
myFunc
();
詳細情報: 「モジュール」の章を参照してください。
これで ES6 の第一歩を踏み出したので、章を参照して探索を続けることができます。各章では、機能または関連機能のセットについて説明し、概要から始まります。最後の章は、これらの概要セクションをすべて 1 か所に集めています。