1. ホーム
  2. ウェブ

フロントエンド開発者が知っておくべきES6新機能トップ10

2022-02-26 09:09:23

AlloyTeamより転載。 フロントエンド開発者が知っておくべきES6機能トップ10

ES6(ECMAScript 2015)の登場は、確かにフロントエンド開発者に新しい驚きをもたらしました。多くの複雑な操作を簡単に実装し、開発者の効率を向上させる素晴らしい新機能がいくつか含まれています。

 この記事は、ES6について簡単に紹介したものです。 主に翻訳したものです。   http://webapplog.com/ES6/comment-page-1/ . もしかしたら、ES6が何なのか知らないかもしれませんが、実は新しいjavascriptの仕様なんです。誰もが忙しいこのご時世、ES6の概要をざっと知りたいなら、この先を読んで、現在最も人気のあるプログラミング言語であるJavaScriptの最新世代の機能トップ10について学んでください。

ES6の優れた機能トップ10を紹介します(順不同)。

  1. ES6におけるデフォルトのパラメータ
  2. ES6におけるテンプレート・リテラル
  3. ES6における複数行の文字列
  4. ES6におけるデストラクチャリング・アサインメント
  5. ES6で強化されたオブジェクトリテラル
  6. ES6におけるアローファンクション
  7. ES6におけるプロミス
  8. ブロック・スコープ付きコンストラクタLetとConst
  9. ES6におけるクラス
  10. ES6におけるモジュール

免責事項:これらのリストは、個人的かつ主観的な意見に過ぎません。決して他のES6機能を否定するものではなく、より一般的に使用される10個の機能のみをここにリストアップしています。

まずは、JavaScriptの歴史を振り返ることから始めましょう。歴史を知らずに、なぜJavaScriptがこのように進化したのかを理解することは難しいでしょう。

ここでは、JavaScriptの発展を簡単な年表で紹介します。

1. 1995: JavaScriptが誕生し、当初の名称はLiveScriptだった。

2. 1997年:ECMAScript規格が制定される。

3. 1999: ES3が登場し、同時にIE5が大流行。

4. 2000-2005: XMLHttpRequest、別名AJAXは、Outlook Web Access (2000), Oddpost (2002), Gmail (2004), Google Maps (2005) で多用されました。

5, 2009: ES5が登場し、foreach、Object.keys、Object.create、JSONなどの標準規格が登場しました。

6, 2015: ES6/ECMAScript 2015が登場。

歴史的な振り返りはここまでにして、本題に入りましょう。

1. ES6 のデフォルト・パラメータ

以前(ES5)は、以下のようにデフォルト・パラメータを定義していたことを思い出してください。

var link = function (height, color, url) {
  var height = height || 50;
  var color = color || 'red';
  var url = url || 'http://azat.co';
    ...
}

パラメータの値が0になるまではすべてうまくいきます。JavaScriptでは、0はfaslyを意味し、デフォルトでハードコードされている値で、パラメータ自体の値にすることはできないので、問題があります。

もちろん、どうしても0を値として使わなければならない場合は、この欠点を無視して論理ORを使えばいいんですよ!?

しかし、ES6では、関数の宣言にデフォルト値を入れればいいのです。

var link = function(height = 50, color = 'red', url = 'http://azat.co') {
  ...
}

ちなみに、この構文はRubyと似ていますよ。

2. ES6 のテンプレート・リテラル

他の言語では、テンプレートを使って値を挿入することで、文字列の中に変数を出力する方法があります。

そこで、ES5では、このように文字列を組み合わせることができます。

var name = 'Your name is ' + first + ' ' + last + '.' ;
var url = 'http://localhost:3000/api/messages/' + id;

幸いなことに、ES6では、新しい構文$ {NAME}を使い、バッククォートで囲むことができます

var name = `Your name is ${first} ${last}. `;
var url = `http://localhost:3000/api/messages/${id}`;

3.ES6における複数行の文字列

ES6における複数行の文字列は、非常に便利な機能です。

ES5では、複数行の文字列を表現するために、以下の方法を用いる必要がありました。

var roadPoem = 'Then took the other, as just as fair,nt'
  + 'And having perhaps the better claimnt'
  + 'Because it was grassy and wanted wear,nt'
  + 'Though as for that the passing therent'
  + 'Had worn them really about the same,nt';
    
var fourAgreements = 'You have the right to be you.n
  You can only be you when you do your best.';

しかし、ES6では、単にバッククォートを使うことで問題が解決します。

var roadPoem = `Then took the other, as just as fair,
  And having perhaps the better claim
  Because it was grassy and wanted wear,
  Though as for that the passing there
  Had worn them really about the same,`;
    
var fourAgreements = `You have the right to be you.
  You can only be you when you do your best.`;

4.ES6におけるアサインメントのデストラクチャリング

デストラクチャリングは、理解するのが難しい概念かもしれません。houseとmouseがキーで、houseとmouseが変数という簡単な代入から始めてみましょう。

ES5では次のようになります。

// data has properties house and mouse
var data = $('body').data();
var house = data.house,
var mouse = data.mouse;


で、node.jsのES5ではこうです。

var jsonMiddleware = require('body-parser').jsonMiddleware ;

// body has username and password
var body = req.body;
var username = body.username,
var password = body.password;

ES6では、上記のES5コードの代わりに、これらのステートメントを使用することができます。

// we'll get house and mouse variables
var { house, mouse } = $('body').data();
var { jsonMiddleware } = require('body-parser');
var { username, password } = req.body;

これは、配列に対しても有効であり、本当に素晴らしい使い方です。

var [col1, col2] = $('.column');
var [line1, line2, line3, , line5] = file.split('n');

分解された代入構文の使い方に慣れるまで時間がかかるかもしれませんが、予想外の効果がたくさんあります。

5. ES6 で強化されたオブジェクト・リテラル

オブジェクト・リテラルを使うと、予想外のことがたくさんできるようになります ES6では、ES5のJSONをクラスにより近づけることができます。

以下は、いくつかのメソッドとプロパティを持つ典型的なES5オブジェクトのテキストです。

var serviceBase = {
  port: 3000,
  url: 'azat.co',
};
var getAccounts = function() { 
  return [1,2,3];
};
var accountServiceES5 = {
  port: serviceBase.port,
  url: serviceBase.url,
  getAccounts: getAccounts,
  toString: function() {
    return JSON.stringify(this.valueOf());
  },
  getUrl: function() {
    return "http://" + this.url + ':' + this.port;
  },
  valueOf_1_2_3: getAccounts(),
}

もっと面白くしたい場合は、以下のようにObject.createを使ってserviceBaseからプロトタイプを継承することができます。

var accountServiceES5ObjectCreate = Object.create(serviceBase);
var accountServiceES5ObjectCreate = {
  getAccounts: getAccounts,
  toString: function() {
    return JSON.stringify(this.valueOf());
  },
  getUrl: function() {
    return 'http://' + this.url + ':' + this.port;
  },
  valueOf_1_2_3: getAccounts(),
}

accountServiceES5ObjectCreateとaccountServiceES5が同一でないことは、オブジェクト(accountServiceES5)が__proto__オブジェクトに以下のプロパティを持つことから分かります。

例のため、両者の類似性を考慮する。つまり、ES6のオブジェクトテキストでは、getAccounts: getAccountsを直接代入するか、getAccountsの

また、ここでは('proto'経由ではなく)__proto__経由でプロパティを以下のように設定します。

var serviceBase = {
  port: 3000,
  url: 'azat.co',
};
var getAccounts = function() {
  return [1,2,3];
};
var accountService = {
  __proto__: serviceBase,
  getAccounts,



あるいは、スーパープリコーションを呼び出して、動的なキー値 (valueOf_1_2_3) を使用することもできます。

  toString() {
    return JSON.stringify((super.valueOf()));
  },
  getUrl() {
    return "http://" + this.url + ':' + this.port;
  },
  [ 'valueOf_' + getAccounts().join('_') ]: getAccounts()
};
console.log(accountService)

ES6のオブジェクトテキストは、古いバージョンのオブジェクトテキストを大きく改善したものです。

6. ES6 のアロー関数

これは待ち遠しい機能ですね。CoffeeScriptが多くの開発者に愛用されているのは、その豊富なarrow関数にあります。ES6でも、豊富な矢印関数のセットがあります。

これらの豊富な矢印は、次のような多くの操作を可能にするので素晴らしいです。

以前はクロージャを使うと、これがいつも予想外に変化していました。アロー関数の魅力は、あなたのこのが期待通りに使えるようになったこと、そしてアロー関数の内部では、これがそのまま使えることです。

ES6のアロー関数では、that = thisやself = this、_this = this、.bind(this)を使う必要がない。

例えば、次のようなコードはES5ではあまりエレガントとは言えないでしょう。

var _this = this;
$('.btn').click(function(event) {
  _this.sendData();
});

ES6 では、_this = this を使用する必要はありません。

$('.btn').click((event) => {
  this.sendData();
});

残念ながら、ES6委員会は、以前の関数の渡し方も良い解決策であると判断し、以前の機能をまだ保持しているのです。

ES5のlogUpperCase()関数の呼び出しでテキストを渡す別の例です。

var logUpperCase = function() {
  var _this = this;
 
  this.string = this.string.toUpperCase();
  return function () {
    return console.log(_this.string);
  }
};
 
logUpperCase.call({ string: 'ES6 rocks' })();

また、ES6では、_this: で時間を浪費する必要はありません。

var logUpperCase = function() {
  this.string = this.string.toUpperCase();
  return () => console.log(this.string);
};

logUpperCase.call({ string: 'ES6 rocks' })();

なお、ES6では、必要であれば=>を古い関数と混在させることができます。矢印関数がコード行で使用されると、それは式になります。

暗黙のうちに1つの文の結果を返すことになります。1行を超える場合は、明示的にreturnを使用する必要があります。

これは、メッセージの配列を作成するために使用されるES5コードです。

var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9'];
var messages = ids.map(function (value) {

  // explicit return
  return 'ID is ' + value;
});

ES6では次のようになります。

var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9'];

// implicit return
var messages = ids.map(value => `ID is ${value}`);

ここでは、文字列のテンプレートが使用されていることに注意してください。

arrow関数では、引数が1つの場合は括弧()は省略可能ですが、引数が2つ以上の場合は必要です。

ES5のコードでは、明示的なreturn関数があります。

var ids = ['5632953c4e345e145fdf2df8', '563295464e345e145fdf2df9'];
var messages = ids.map(function (value, index, list) {

  // explicit return
  return 'ID of ' + index + ' element is ' + value + ' ';
});

ES6では、引数を括弧で囲む必要があり、暗黙のうちに返される、より厳密なバージョンがあります。

var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']

// implicit return
var messages = ids.map((value, index, list) => `ID of ${index} element is ${value} `);

7. ES6 のプロミス

プロミスは賛否両論あるトピックです。q, bluebird, deferred.js, vow, avow, jqueryなどです。

また、プロミスは必要ない、非同期、ジェネレータ、コールバックなどを使えば十分だと言う人もいます。しかし,嬉しいことに,ES6には標準的なPromiseの実装があります.

setTimeout()を使って実装した、簡単な非同期遅延ロード関数を紹介します。


setTimeout(function() {
  console.log('Yay!');
}, 1000);

ES6では、これをプロミスでオーバーライドすることができる。

var wait1000 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 1000);
}).then(function() {
  console.log('Yay!');
});

あるいはES6のarrow関数で。

var wait1000 = new Promise((resolve, reject)=> {
  setTimeout(resolve, 1000);
}).then(()=> {
  console.log('Yay!');
});

ここまでで、コード行数は3行から5行に増えましたが、明らかなメリットはありません。実際、setTimeout()コールバック関数にもっとネストされたロジックがあれば、より多くの利益を見出すことができます。

setTimeout(function(){
  console.log('Yay!');
  setTimeout(function(){
    console.log('Wheeyee!');
  }, 1000);
}, 1000);

ES6では、プロミスで書き換えることができます。

var wait1000 = ()=> new Promise((resolve, reject)=> {
  setTimeout(resolve, 1000);
});
wait1000()
  .then(function() {
    console.log('Yay!')
    return wait1000()
  })
  .then(function() {
    console.log('Wheeyee!')
  });

プロミスが通常のコールバックより優れていることにまだ納得していないのですか?実は私も納得していません。一度コールバックのことを考えたら、プロミスの余分な複雑さは必要ないと思います。

ES6にはカルト的な人気を誇るPromisesがありますが。プロミスは賛否両論あるコールバックですが、本当に良い機能です、詳しくはプロミスをご覧ください。 ES6プロミス入門 .

8. Block-Scoped Constructs Let and Const (ブロックスコープとコンストラクタletとconst)

ES6のコードでおなじみのletという図形を見たことがあるかもしれません。letはES6では派手な機能ではなく、より複雑になっています。

Letは変数の新しい宣言方法で、変数のスコープをブロックレベルの内部に保持することができます。私たちは中括弧でコードのブロックを定義していますが、ブロックレベルのスコープはES5では何の役割も果たしません:。

function calculateTotalAmount (vip) {
  var amount = 0;
  if (vip) {
    var amount = 1;
  }

  // more crazy blocks!
  {
    var amount = 100;
    {
      var amount = 1000;
    }
  }

  return amount;
}

console.log(calculateTotalAmount(true));

その結果、1000が返されますが、これは本当にバグです。

ES6では、ブロックレベルのスコープを制限するためにletを使用します。そして、varは関数スコープを制限するためのものです。

function calculateTotalAmount (vip) {

  // probably should also be let, but you can mix var and let
  var amount = 0;
  if (vip) {

    // first amount is still 0
    let amount = 1;
  }

  // more crazy blocks! 
  {
    // first amount is still 0
    let amount = 100;
    {

      // first amount is still 0
      let amount = 1000;
    }
  }
  
  return amount;
}
 
console.log(calculateTotalAmount(true));

ブロックスコープにletがあるため、この結果は0になります。constになると、さらに簡単です。

これは不変量で、これもletと同じようにブロック・スコープが設定されています。

ここでは、異なるブロックスコープに属するため、互いに影響を及ぼさない定数の束を使ったデモを紹介します。

function calculateTotalAmount (vip) {
  const amount = 0;  
  if (vip) {
    const amount = 1;
  }

  // more crazy blocks!
  {
    const amount = 100 ;
    {
      const amount = 1000;
    }
  }

  return amount;
}

console.log(calculateTotalAmount(true));

個人的な見解ですが、letとconstは言語を複雑にしています。それらがなければ、1つの方法だけを考えればよかったのに、今では多くのシナリオを考慮しなければならなくなったのです。

9. ES6 のクラス

もしあなたがオブジェクト指向プログラミング(OOP)が好きなら、この機能を気に入るはずです。Facebookにコメントを書くのと同じように、クラスや継承を簡単に書くことができるようになる。

古いES5では、クラスというキーワードがなかったため、クラスの作成と使用は本当に頭痛の種でした(保持はされていましたが、何もできませんでした)。その上、多くの継承モデル、たとえば 擬似クラシック クラシック 機能的  さらに混乱に拍車をかけているのが、JavaScript間の宗教戦争である。

ES5でクラスを書くにはいろいろな方法があるので、ここでは割愛します。では、関数を使わず、プロトタイプを使ってクラスを実装するES6でのクラスの書き方を見てみましょう。baseModelというクラスを作成し、そのクラスにコンストラクタとgetName()メソッドを定義します。

class baseModel {

  // class constructor, node.js 5.6 does not support passing options = {}, data = [] for now
  constructor(options, data) {
    this.name = 'Base';
    this.url = 'http://azat.co/api';
    this.data = data;
    this.options = options;
  }
 
  // class method
  getName() {
    console.log(`Class name: ${this.name}`);
  }
}

オプションとデータには、デフォルトのパラメータ値を使用していることに注意してください。また、メソッド名には function キーワードは不要で、コロン (:) も不要です。

もうひとつの大きな違いは、thisという属性を代入する必要がないことです。これで、属性の値を設定するのは、コンストラクタで代入するだけでよくなりました。

AccountModel は baseModel クラスを継承しています。

class AccountModel extends baseModel {
  constructor(options, data) {

親コンストラクタを呼び出すには、次のパラメータを渡すと super() を簡単に呼び出すことができます。

    // call the parent method with super
    super({private: true}, ['32113123123', '524214691']);
    this.name = 'Account Model';
    this.url += '/accounts/';
  }

もっと遊び心のあることをしたい場合は、accountDataの属性に

  // calculated attribute getter
  get accountsData() {
  // ... make XHR
    return this.data;
  }
}

では、どのように呼び出すのでしょうか。それは、とても簡単です。

let accounts = new AccountModel(5);
accounts.getName();
console.log('Data is %s', accounts.accountsData);

その結果、驚くべきことに、出力は

クラス名:Account Model

データは32113123123,524214691です。

10. ES6 のモジュール

ES6以前のJavaScriptがネイティブモジュールをサポートしていなかったことはよく知られている。人々は、AMD、RequireJS、CommonJS、その他の回避策を考え出しました。現在では、ES6でモジュールのインポートおよびエクスポート操作を使用することが可能になっています。 

ES5では、実行可能なコードを直接<script>(IIFEと呼ばれる)か、AMDのようなライブラリで記述することができました。しかし、ES6では、exportでクラスをインポートすることができます。

以下はその例で、ES5ではmodule.jsはport変数とgetAccountsメソッドを持っています。

module.exports = {
  port: 3000,
  getAccounts: function() {
    ...
  }
}

ES5では、main.jsはmodule.jsをインポートするためにrequire('module')に依存する必要があります。

var service = require('module.js');

// 3000
console.log(service.port);

しかし、ES6では、exportとimportを使う。

例えば、ここにES6で書かれたmodule.jsファイルのライブラリがあります。

export var port = 3000;
export function getAccounts(url) {
  ...
}

ES6 を使用してファイル main.js にインポートする場合、import {name} from 'my-module' 構文を使用する必要があります、例えば、次のようになります。

import {port, getAccounts} from 'module';

// 3000
console.log(port);

あるいは、main.jsでモジュール全体をインポートして、それをserviceと名付けることもできます。

import * as service from 'module';

// 3000
console.log(service.port);

個人的な見解ですが、ES6モジュールは分かりづらいと思います。しかし、ひとつだけ確かなことは、このモジュールは言語をより柔軟にしてくれるということです。

すべてのブラウザがES6モジュールをサポートしているわけではないので、ES6モジュールに対応するためにはjspmなどを使う必要があります。

ES6モジュールに関する詳細な情報や例については  このテキスト . とにかく、モジュール化されたJavaScriptを書くようにお願いします。

ES6(Babel)の使い方

ES6 は最終的に決定されましたが、すべてのブラウザで完全にサポートされているわけではありません。 http://kangax.github.io/compat-table/es6/ . ES6を使用するには、babelなどのコンパイラが必要です。

grunt、gulp、webpackはすべてbabelをサポートするプラグインを持っています。

<イグ

gulp-babelプラグインをインストールした、gulpの事例です。

$ npm install --save-dev gulp-babel

gulpfile.jsで、タスクビルドを定義し、src/app.jsに入れ、ビルドファイルでコンパイルします。

var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('build', function () {
  return gulp.src('src/app.js')
    .pipe(babel())
    .pipe(gulp.dest('build'));
});

Node.jsとES6

nodejsでは、ビルドツールまたはスタンドアロンのBabelモジュールbabel-coreを使用して、Node.jsファイルをコンパイルすることができます。

以下のようにインストールします。

$ npm install --save-dev babel-core

そして、node.jsでは、この関数を呼び出すことができます。

require("babel-core").transform(ES5Code, options);

ES6の概要

ES6のその他の機能で、利用できそうなものを順不同で紹介します。

1. 新しいMath、Number、String、Array、Objectメソッド

2. 2進数および8進数データ型

3. デフォルトパラメータ 不定形パラメータ展開演算子

4、シンボル記号

5. テールコール

6、ジェネレーター(発電機)

7、MapやSetなどの新しいデータ構造(MAPやSetなどの新しいデータ構造)

参考

  1. ES6 Cheatsheet  ( 無料PDF )
  2. http://webapplog.com/ES6/comment-page-1/
  3. ECMAScript 6を理解するために Nicolas Zakas著
  4. http://ES6-features.org/#DateTimeFormatting
  5. IIFE: すぐに実行される関数式