モジュラー
ES6 では、モジュール性が JavaScript の標準機能になります。ES6 のモジュール性は、JavaScript コードを編成および管理するためのよりエレガントで保守しやすい方法を提供し、グローバル変数の汚染や名前の競合を効果的に回避できます。ES6 モジュール性の主な機能の一部を以下に示します。
- エクスポート:他のモジュールで使用するために、キーワードを使用して
export
変数、関数、またはクラスをモジュールにエクスポートできます。
たとえば、次のコードは関数 square をモジュールとしてエクスポートします。
// module.js
export function square(x) {
return x * x;
}
- インポート:キーワードを使用して他のモジュールから変数、関数、またはクラスをインポートし
import
、現在のモジュールで使用できます。
たとえば、次のコードは module.js モジュールから square 関数をインポートして使用します。
// app.js
import {
square } from './module.js';
console.log(square(5)); // 25
- デフォルトのエクスポート:
export default
変数、関数、またはクラスは、構文を通じてデフォルトでモジュールとしてエクスポートできます。
たとえば、次のコードは、デフォルトで関数 add をモジュールとしてエクスポートします。
// module.js
export default function add(x, y) {
return x + y;
}
- デフォルトのインポート:
import
変数、関数、またはクラスは、構文を介して他のモジュールからデフォルトでインポートし、現在のモジュールで使用できます。
たとえば、次のコードは、デフォルトで module.js モジュールから add 関数をインポートして使用します。
// app.js
import add from './module.js';
console.log(add(2, 3)); // 5
つまり、ES6 のモジュール性は、JavaScript コードを編成および管理するためのより柔軟で保守しやすい方法を提供し、グローバル変数の汚染や名前の競合を効果的に回避できます。
クラスクラス
ES6 では、class
オブジェクトを定義および使用するためのより簡潔でオブジェクト指向の方法を提供するキーワードが導入されました。class
これは、クラスを定義し、クラスのインスタンスを作成できる JavaScript の特別な関数とみなすことができます。class
ES6 の主な機能の一部を次に示します。
- クラス定義:キーワードを使用して
class
クラスを定義します。
たとえば、次のコードは Person という名前のクラスを定義します。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hello, my name is ${
this.name}, I'm ${
this.age} years old.`);
}
}
- コンストラクター:クラスのコンストラクターを定義するには、コンストラクター メソッドを使用します。
たとえば、次のコードは Person クラスのコンストラクターを定義します。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
- クラス メソッド:クラス メソッドを使用して、クラスのメソッドを定義します。
たとえば、次のコードは Person クラスの SayHello メソッドを定義します。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hello, my name is ${
this.name}, I'm ${
this.age} years old.`);
}
}
- クラスの継承: extends キーワードを使用してクラスの継承を実装します。
たとえば、次のコードは、Person クラスを継承する Student クラスを定義します。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hello, my name is ${
this.name}, I'm ${
this.age} years old.`);
}
}
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
study() {
console.log(`${
this.name} is studying in grade ${
this.grade}.`);
}
}
- super キーワード: super キーワードを使用して、親クラスのコンストラクターとメソッドを呼び出します。
たとえば、次のコードは、super キーワードを使用して Person クラスのコンストラクターを呼び出します。
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
}
つまり、ES6 はclass
オブジェクトを定義して使用するためのより簡潔でオブジェクト指向の方法を提供し、これにより JavaScript コードの作成とメンテナンスが大幅に簡素化されます。同時に、ES6 はclass
継承やポリモーフィズムなどのオブジェクト指向プログラミングの重要な機能もサポートしており、JavaScript コードをより柔軟でスケーラブルにします。
シンボル
ES6 では、新しいプリミティブ データ型 が導入されていますSymbol
。これは、オブジェクトのプロパティの一意の識別子として使用できる不変のプリミティブ値です。各Symbol
値は一意であり、繰り返されることはありません。Symbol
文字列に似たデータ型ですが、その値は一意で不変であり、他の型に自動的に変換されません。
Symbol()
この関数を使用して新しい値を作成できます。この値は、値の目的をSymbol
説明するパラメータとしてオプションの説明文字列を受け入れることができますが、この説明文字列は値の一意性に影響を与えません。Symbol
Symbol
のいくつかの機能を次に示しますSymbol
。
Symbol
この値はオブジェクトの属性名として使用でき、それぞれのSymbol
値は一意であるため、名前の競合の問題は発生しません。オブジェクト リテラルでは、Symbol
角かっこ構文を使用してプロパティを定義できます。
const mySymbol = Symbol();
const obj = {
[mySymbol]: 'value'
};
console.log(obj[mySymbol]); // 输出 'value'
Symbol
値は自動的に文字列に変換されないため、オブジェクトのプロパティ名の一部として使用できません。それ以外の場合は、TypeError
エラーがスローされます。
const mySymbol = Symbol();
const obj = {
};
// 正确做法:将 Symbol 作为属性名
obj[mySymbol] = 'value';
// 错误做法:将 Symbol 转换成字符串作为属性名
obj[mySymbol.toString()] = 'value'; // 抛出 TypeError 错误
- 組み込み値には、オブジェクトのデフォルトのイテレータ、カスタム動作などを指定するために使用される、など
Symbol
の特別な意味があります。Symbol.iterator
Symbol.hasInstance
instanceof
const arr = [1, 2, 3];
const iter = arr[Symbol.iterator]();
console.log(iter.next()); // 输出 { value: 1, done: false }
console.log(iter.next()); // 输出 { value: 2, done: false }
console.log(iter.next()); // 输出 { value: 3, done: false }
console.log(iter.next()); // 输出 { value: undefined, done: true }
Symbol
値は定数として使用して、名前の競合を避けることができます。たとえば、Symbol
他のイベント名と競合しないように、イベント名として値を使用できます。
const EVENT_A = Symbol('event_a');
const EVENT_B = Symbol('event_b');
// 发送事件 A
eventEmitter.emit(EVENT_A);
// 监听事件 B
eventEmitter.on(EVENT_B, () => {
// do something
});
要約すると、Symbol
これはオブジェクトのプロパティ名として使用できる一意の識別子であり、定数の定義やデフォルトのイテレータの指定などに使用できます。この機能の登場により、JavaScript でのオブジェクト プロパティ名の命名がより柔軟かつ充実したものになりました。
アロー関数
ES6 では、新しい関数定義構文としてアロー関数が導入されています。アロー関数には、従来の関数定義方法と比較して、いくつかの特殊な構文と動作があります。
特徴は以下のとおりです。
-
簡潔な構文: アロー関数は
=>
矢印 ( ) を使用して定義され、function
関数本体内のキーワードと中括弧は省略されます。関数本体にステートメントが 1 つしかない場合は、return キーワードを省略でき、式の結果が暗黙的に返されます。// 传统函数定义 function add(a, b) { return a + b; } // 箭头函数定义 const add = (a, b) => a + b;
-
this
アロー関数には、独自の、arguments
、super
またはがありませんnew.target
。これらは、外側のスコープから対応する値を継承します。これは、アロー関数内でthis
指されるコンテキスト オブジェクトは、関数が呼び出されたときのオブジェクトではなく、関数が定義されたときのコンテキスト オブジェクトであることを意味します。const person = { name: 'John', sayHello: function () { setTimeout(() => { console.log(`Hello, ${ this.name}!`); }, 1000); } }; person.sayHello(); // 输出 "Hello, John!"
-
アロー関数をコンストラクターとして使用することはできません。また、
new
キーワードを使用してオブジェクトをインスタンス化することもできません。アロー関数にはプロパティがないprototype
ため、new
キーワードを使用してオブジェクト インスタンスを作成できません。const Person = (name) => { this.name = name; // 错误:箭头函数不能用作构造函数 }; const john = new Person('John'); // 错误:无法使用new关键字实例化对象
-
アロー関数にパラメータが 1 つだけある場合は、パラメータのかっこを省略できますが、パラメータがない場合、または複数のパラメータがある場合は、かっこを使用する必要があります。
// 一个参数 const greet = name => console.log(`Hello, ${ name}!`); // 没有参数 const sayHello = () => console.log('Hello!'); // 多个参数 const add = (a, b) => a + b;
アロー関数は、多くのシナリオで関数定義を簡素化し、特にコールバック関数の処理、コンテキスト バインディングの処理、関数のネストの簡素化に役立ちます。this
ただし、アロー関数と従来の関数の間には、特にコンテキストを扱うときの動作に注意が必要な違いがあります。
代入の分割
ES6 の分割代入は、配列またはオブジェクトから値を抽出して変数に割り当てるための便利な構文です。これにより、簡潔な方法でコードを記述し、複雑なデータ構造から必要な値を迅速に抽出することができます。
構造化代入は配列とオブジェクトに適用できます。以下で 2 つのケースについて詳しく説明します。
-
配列の構造化代入:
配列分割代入を使用すると、特定のパターンに従って配列から値を抽出し、それらを変数に割り当てることができます。パターン マッチングは配列の位置に基づいて行われます。
const [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5]
上記の例では、配列分割代入を使用して、
[1, 2, 3, 4, 5]
配列内の値を変数およびa
、にそれぞれ割り当てます。配列の最初と 2 番目の要素をそれぞれ受け取り、残りの要素を新しい配列として受け取ります。b
rest
a
b
rest
-
オブジェクトの分割と代入:
オブジェクトの構造化割り当てを使用すると、オブジェクトから属性値を抽出し、属性名で照合して変数に割り当てることができます。
const person = { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }; const { name, age, address: { city, country } } = person; console.log(name); // 'Alice' console.log(age); // 25 console.log(city); // 'New York' console.log(country); // 'USA'
上記の例では、オブジェクト分割代入を使用して、オブジェクトから
person
プロパティname
、age
、address.city
および を抽出しaddress.country
、それらを対応する変数に割り当てます。コロンを
:
使用して、割り当てられたプロパティを構造化するためのエイリアスを指定できることに注意してください。上の例では、person.address
の値を変数に代入しaddress
、address
さらにcity
とを分解しますcountry
。
分割代入では、デフォルト値、入れ子構造、特定の要素やその他の関数の無視もサポートされており、特定のニーズに応じて柔軟に使用できます。複雑なデータ構造を扱う場合、コードの読みやすさと書き込み効率を向上させることができます。
残りのパラメータ
ES6 では、残りのパラメータ (残りのパラメータ) の概念が導入されており、これにより、無限の数のパラメータを配列として表現できるようになります。関数宣言では、残りのパラメーターは 3 つのドット (…) とそれに続くパラメーター名で表されます。これにより、関数に渡される追加のパラメーターを簡単に処理できるようになります。
以下は、残りのパラメーターのいくつかの特性と使用法の詳細な説明です。
-
文法:
function functionName(...rest) { // 函数体 }
関数宣言では、
...rest
フォームを使用して残りのパラメータを定義します。rest
関数の呼び出し時に渡されるすべての追加パラメータを含む配列です。 -
冗長パラメータの処理:
関数の呼び出し時に複数のパラメータが渡され、関数宣言で少数のパラメータのみが定義されている場合、冗長パラメータは残りのパラメータにキャプチャされます。function sum(...rest) { let total = 0; for (let num of rest) { total += num; } return total; } console.log(sum(1, 2, 3, 4, 5)); // 15
上の例では、
sum
関数のパラメーター リストに残りのパラメーターが 1 つだけありますが、任意rest
の数のパラメーターを関数に渡し、関数本体の配列を反復処理することで合計を計算できます。sum
rest
-
残りのパラメータは他のパラメータと組み合わせて使用されます。
関数宣言では、残りのパラメータは他のパラメータと共存できますが、残りのパラメータは最後のパラメータである必要があります。function foo(a, b, ...rest) { console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5] } foo(1, 2, 3, 4, 5);
上の例では、
a
と はb
通常のパラメータですrest
が残りのパラメータは関数に渡される追加パラメータを受け取ります。 -
残りのパラメータの適用:
- 残りのパラメータを収集する: 関数の呼び出し時に渡されるパラメータの数が不明な場合は、関数本体での処理のために残りのパラメータを使用して残りのパラメータを収集できます。
- 代替引数オブジェクト: ES6 の REST パラメータはより直感的で使いやすいのに対し、
arguments
オブジェクトは配列のようなオブジェクト、REST パラメータは実数の配列であり、配列のさまざまなメソッドが使用できます。 - 関数パラメータの柔軟性: 残りのパラメータを使用すると、固定数のパラメータを事前に指定せずに、任意の数のパラメータを受け取る関数を宣言できます。
概要: ES6 の残りのパラメータは、不特定の数のパラメータを処理し、それらを配列に収集し、関数本体で操作する方法を提供します。これにより、関数宣言がより柔軟になり、冗長パラメーターの処理がより便利で読みやすくなります。
セット/マップ
ES6 では、2 つの新しいデータ構造とSet
が導入されており、データ コレクションとキーと値のペアを処理するためのより便利で効率的な方法が提供されます。Map
-
セット:
- セットは、順序付けされておらず、繰り返しのないデータのコレクションです。
- そのメンバー値は一意であり、繰り返されません。
- プリミティブ値や参照値など、あらゆる種類の値を保存できます。
- Set 内の要素にはインデックスが付けられず、インデックスによってアクセスすることはできません。
- 主なアプリケーション シナリオは、重複排除と要素が存在するかどうかの判断です。
const set = new Set(); set.add(1); set.add(2); set.add(3); set.add(2); // 添加重复元素,但不会生效 console.log(set.size); // 3 console.log(set.has(2)); // true set.delete(3); console.log(set.size); // 2 set.clear(); console.log(set.size); // 0
-
地図:
- マップは、オブジェクトと同様に、キーと値のペアのコレクションです。
- そのキーと値は、プリミティブ値や参照値を含む、任意のタイプのデータにすることができます。
- Map 内のキーと値のペアは順序付けされています。
- キーを使用して、対応する値を取得できます。
const map = new Map(); const key1 = 'key1'; const key2 = { name: 'John' }; map.set(key1, 'value1'); map.set(key2, 'value2'); console.log(map.size); // 2 console.log(map.get(key1)); // 'value1' map.delete(key2); console.log(map.size); // 1 console.log(map.has(key2)); // false map.clear(); console.log(map.size); // 0
keys()
Map には、やvalues()
などの反復子 (Iterator) メソッドも用意されておりentries()
、これらを使用して Map のキー、値、およびキーと値のペアを走査することができます。const map = new Map(); map.set('a', 1); map.set('b', 2); map.set('c', 3); for (let key of map.keys()) { console.log(key); // 'a', 'b', 'c' } for (let value of map.values()) { console.log(value); // 1, 2, 3 } for (let [key, value] of map.entries()) { console.log(key, value); // 'a' 1, 'b' 2, 'c' 3 }
Map は、初期化するパラメータとして配列を受け入れることもできます。
const array = [['a', 1], ['b', 2], ['c', 3]]; const map = new Map(array); console.log(map.get('a')); // 1
Set と Map は効率的なデータ処理方法を提供し、コレクションとキーと値のペアを管理する必要があるシナリオに適しています。これらは、操作がより直観的かつ効率的になり、パフォーマンスと拡張性が向上するように設計および使用されています。## let/const
テンプレート文字列
ES6 では、文字列を処理するためのより便利で柔軟な方法を提供するテンプレート文字列 (Template Strings) が導入されています。
テンプレート文字列はバッククォート (`) で囲まれた文字列であり、次の機能をサポートします。
-
文字列補間:構文
を使用して${}
、変数または式をテンプレート文字列に挿入します。const name = 'John'; const age = 30; const message = `My name is ${ name} and I'm ${ age} years old.`; console.log(message); // "My name is John and I'm 30 years old."
内部的には
${}
、変数、関数呼び出し、演算子などを含む任意の JavaScript 式を使用できます。 -
複数行の文字列:
テンプレート文字列は、エスケープ文字や連結演算子を使用せずに複数行にまたがることができます。const multiline = ` This is a multiline string. `; console.log(multiline); /* "This is a multiline string." */
複数行の文字列では、テンプレート文字列のインデントと改行が保持されるため、コードが読みやすくなります。
-
ネストされたテンプレート文字列:
テンプレート文字列内に他のテンプレート文字列をネストして、より複雑な文字列を構築できます。const name = 'John'; const message = `Welcome to our website, ${ name}! Today's special offer: Buy 1 get 1 free! Offer valid until ${ new Date().toLocaleDateString()}.`; console.log(message); /* "Welcome to our website, John! Today's special offer: Buy 1 get 1 free! Offer valid until 5/11/2023." */
上の例では、
${name}
外側のテンプレート文字列内にネストされ、${new Date().toLocaleDateString()}
内側のテンプレート文字列内にネストされています。 -
生の文字列:
テンプレート文字列にプレフィックスを付けると、String.raw
バックスラッシュをエスケープしない生の文字列が作成されます。const path = String.raw`C:\Users\John\Documents\file.txt`; console.log(path); // "C:\Users\John\Documents\file.txt"
上記の例では、バックスラッシュは元の文字列内で変更されず、特殊文字としてエスケープされません。
テンプレート文字列は、特に変数を挿入したり複雑なテキストを作成する必要がある場合に、文字列を操作するためのより直感的で便利な方法を提供します。これを使用すると、コードの可読性と保守性が向上し、文字列の連結とエスケープの面倒な操作が軽減されます。
スプレッド演算子
ES6 のスプレッド演算子 (Spread Operator) は、反復可能なオブジェクト (配列、文字列、配列のようなオブジェクトなど) をスプレッドするために使用される 3 つの連続したドット (...) です。
スプレッド演算子には、次の主な用途と機能があります。
-
配列の拡張:
スプレッド演算子は、配列を複数の独立した要素に拡張できます。const arr = [1, 2, 3]; console.log(...arr); // 1 2 3
これにより、配列の要素を関数に渡したり、複数の配列を結合したりすることが簡単になります。
-
文字列展開:
スプレッド演算子は、文字列を個々の文字に展開できます。const str = 'hello'; console.log(...str); // "h" "e" "l" "l" "o"
これは、文字列を 1 文字ごとに処理する必要がある操作に役立ちます。
-
オブジェクトの展開:
スプレッド演算子は、オブジェクトを複数のキーと値のペアに展開できます。const obj = { x: 1, y: 2 }; console.log({ ...obj }); // { x: 1, y: 2 }
これは、オブジェクトのコピー、オブジェクトの結合、または新しいオブジェクトの作成に使用できます。
-
関数呼び出し時のパラメーターの受け渡し:
スプレッド演算子は、配列または配列のようなオブジェクトの要素を関数のパラメーターとして渡すことができます。function sum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; console.log(sum(...numbers)); // 6
これにより
apply()
、パラメータを使用したり手動でパラメータを分割したりする手間が省けます。 -
配列とオブジェクトの浅いコピー:
スプレッド演算子を使用して、配列とオブジェクトの浅いコピーを作成できます。const arr = [1, 2, 3]; const arrCopy = [...arr]; const obj = { x: 1, y: 2 }; const objCopy = { ...obj };
これにより、同じデータを参照するのではなく、元の配列とオブジェクトのコピーが作成されます。
スプレッド演算子は、配列、文字列、オブジェクトを操作するための簡潔かつ柔軟な方法を提供し、コードをより読みやすく、保守しやすくします。これは、関数呼び出し、配列のマージ、オブジェクトのコピーなどのシナリオで非常に役立ち、関連する操作のコードを大幅に簡素化できます。
イテレータ/ジェネレータ
ES6 では、反復可能オブジェクトと反復可能オブジェクトを生成する関数の処理に使用されるイテレーターとジェネレーターの概念が導入されています。
-
イテレータ:
イテレータは、データのコレクションに順次アクセスする方法を提供するオブジェクトです。これには、呼び出しごとにとプロパティnext()
を含むオブジェクトを返すメソッドがあります。value
done
value
: イテレータによって現在返される値を示します。done
: 反復子がすべての要素を走査したかどうかを示します。そうであれば、true
反復子が終了したことを意味します。それ以外の場合はfalse
、 。
イテレータは手動で実装することも、ES6 が反復可能なオブジェクト (配列、文字列、セット、マップなど) に提供する組み込みイテレータを使用することもできます。
const arr = [1, 2, 3]; const iterator = arr[Symbol.iterator](); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
-
Iterable:
iterable は、反復 (走査) できるデータのコレクションであるイテレーターを備えたオブジェクトです。反復可能オブジェクトには、Symbol.iterator
反復子オブジェクトを返す名前のメソッドが必要です。組み込みの反復可能なオブジェクトには、配列、文字列、セット、マップなどが含まれます。
const arr = [1, 2, 3]; const str = 'hello'; const set = new Set([1, 2, 3]); const map = new Map([['a', 1], ['b', 2], ['c', 3]]); console.log(arr[Symbol.iterator]); // [Function: values] console.log(str[Symbol.iterator]); // [Function: [Symbol.iterator]] console.log(set[Symbol.iterator]); // [Function: values] console.log(map[Symbol.iterator]); // [Function: entries]
-
ジェネレーター:ジェネレーターは、キーワードを使用して定義され、関数本体内のステートメントを使用して関数の実行を一時停止し、反復子オブジェクトを返す
特別な関数です。function*
yield
ジェネレーター関数はイテレーターを通じて徐々に値を生成できます。ジェネレーター関数のメソッドが呼び出されるたびに
next()
、次のステートメントが実行され、と属性yield
を含むオブジェクトが返されます。value
done
function* generator() { yield 1; yield 2; yield 3; } const iterator = generator(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }