ES6(ES2015)の新しい機能(ES7, 8, 9は一旦スルー...)
ES6, 7, 8, 9と無視できないレベルになってきた。
ECMAScriptとは
- Ecma Internationalによって標準化された言語仕様
- JavaScriptはECMAScriptの仕様を元に実装されている
- 毎年バージョンアップされていて、今はES9(ES2018)まで正式リリースされている
- ES6なのに2015年というややこしさは有名
- ブラウザ対応のカバレッジがまだ100%ではない 参考
とはいえ時間の問題なとこもあるので、ES6の重要機能を勉強しておく。
ブロックスコープの宣言
ブロックスコープがES6より利用可能に。 変数を宣言するには、var命令ではなくlet命令を使う。
if (true) { let hoge = 'hoge'; } console.log(hoge); // エラー
let命令では、同じスコープ内での変数の重複を認めない仕様になっている。
ES6以降もvar命令は利用可能ではあるが、基本的にlet命令。
定数の宣言
定数も従来のJSには存在しない概念だったが、ES6からconst命令により宣言できる。
const hoge = 'hoge'; hoge = 'fuga' // hogeは定数なのでエラー
const命令は「変更禁止」ではなく「再代入禁止」なので
const arr = [1, 2, 3]; arr[0] = 5; console.log(arr); // []
このような記述はできる。
テンプレート文字列
PHPでも利用可能なヒアドキュメントのようなもの。
ES6以降は、値をバッククォートで括ることで実現できる。
- 改行をそのまま書ける
- 変数を文字列に埋め込める
などのメリットがある。
文字列を変数に埋め込む時は、${...}と記述する。
let val = `Java Script`; console.log(val); // Java Script let name = 'jsman'; let str = `My Name is ${name}!` console.log(str); // My name is jsman!
分割代入
ES6では複数の変数に対して、一度で複数の値を代入することができる。
この分割代入では、変数の他にオブジェクトのプロパティに対しても同様に値の代入が可能。
let [name, age] = ['ryutaro', 25]; let {name, age, tel} = {name:'ryutaro', age:25};
代入時に足りない分はundefinedになり、余った分は切り捨てられる仕様となる。
for...of
for...inは対象オブジェクトのプロパティ名を返却(使い道はあまり...)
for...ofは値を列挙してくれる(foreach文な命令)
let arr = ['ryu', 'tara', 'fukuma']; for (let val in arr) { console. log(val); // 0、 1、 2 と順に表示 } let arr2 = ['ryu', 'taro', 'fukuma']; for (let val2 of arr2) { console. log(val2); // ryu、 taro、 fukuma と 順に 表示 }
引数のデフォルト値
引数の後に=で初期値を記述
function sample(val = 'hoge') { console.log(val); } sample(); // hoge
可変長引数
関数の引数の前にピリオド3つで可変長になる。
argumentsオブジェクトを利用した可変長引数と違うのは、引数に名前を付けられること。
function sumVal(...args) { let result = 0; for (let arg of args) { result += arg; } console.log(result); } sumVal(1, 2, 3); // 6 sumVal(10, 100, 1000) // 1110
アロー関数
アロー関数は、無名関数の定義をより簡潔に記述するための仕組み。
let func = funtion(val) { console.log(val); } let newFunc = (val) => { console.log(val); } func('hoge'); // hoge newFunc('fuga'); // fuga
- 引数が1つの場合は()が省略可能
- 処理が一行の場合は{}やreturnも省略可能 しかしちょっと見慣れない。。。
let func1 = val => { console.log(val); } let func2 = (val1, val2) => val1 + val2; func1('hoge'); // hoge console.log(func2('hoge', 'fuga')); hogefuga
オブジェクトリテラルの進化
プロパティとその値を表す変すが同じ名前であれば、値の指定を省略できる
let name = 'smart phone'; let model = 'xx-xx'; let color = 'blue'; let phone = {name, model, color}; console.log(phone); // Object {name:"smart phone", model:"xx-xx", color:"blue"}
メソッドの定義も直感的に書ける
let phone = { name: 'smart phone', getName() { return `${ this. name} です `; } } console.log(phone. getName()); // smart phone です
クラスの定義
prototypeのクラスっぽい振る舞いとは違い、正式にクラスが使える。
/* プロトタイプ */ let Phone = function(name) { this.setName( name); }; Phone. prototype = { setName : function(name) {this.name = name;}, getName : function() {return '機種は' + this.name + 'です';}, } let smartPhone = new Phone('smart phone'); console.log(smartPhone.getName()); // 機種はsmart phoneです /* クラス */ class Phone { constructor(name) { this.name = name; } set name(name) { this._ name = name; } get name() { return this._name; } getName() { console.log('機種は' + this.name + 'です'); } } let smartPhone = new Phone('smart phone'); smartPhone.getName(); // 機種はsmart phoneです