ES6 基礎#
オブジェクトリテラル#
- プロパティ値の省略
var events = {
listeners: listeners,
listen: listen;
}
==>
var events = { listeners, listen }
- 計算されたプロパティ名
変数 var expertise = 'journalism'
がある場合、
オブジェクトにこのようなプロパティを追加できます:
var person = {
name: 'gui',
age: 27
}
person[expertise] = {
years: 5,
interests: ['a', 'b', 'c']
}
- メソッド定義
プロパティを追加することでオブジェクトにメソッドを宣言します
var emitter = {
on: function (a, b) {
...
}
}
==>
var emitter = {
on(a,b) {
...
}
}
アロー関数#
- スコープ
アロー関数は新しいスコープを作成せず、親のスコープと同じです。クロージャを作成しません。
var timer = {
seconds: 0,
start() {
setInterval(() => {
this.seconds++
},1000)
}
}
//this は timer ブロックのスコープの this
timer.start()
- フォーマット
オブジェクトを返す場合は括弧を使用します:
var objectFactory = () => ({ modular: 'es6' })
分割代入#
- オブジェクトの分割代入
このようなオブジェクトがある場合:
var character = {
name: 'Bruce',
pseudonym: 'Batman',
metadata: {
age: 34,
gender: 'male'
}
}
そのプロパティをこのように取得できます:
var { pseudonym } = character
またはその別名を取得します:
var { pseudonym: pseudonymAlias } = character
深い分割代入:
var { metadata: { gender } } = character
深い分割代入と別名:
var { meatadata: { gender: characterGender } } = character
- 配列の分割代入
基本形式:
var lst = ['a', 'b', 'c']
var [x, y, z] = lst;
スキップ:
var [x, , z] = lst;
デフォルト値:
var [ x = 'x', , z = 'z'] = lst;
交換:
var left = 5
var right = 8
[left, right] = [right, left]
- 関数パラメータのデフォルト値
アロー関数のデフォルト値:
var double = (input = 0) => input * 2
- 関数パラメータの分割代入
基本形式:
function foo({ brand = 'Volkswagen', make = 1999 }) {
console.log(brand)
console.log(make)
}
foo({ make: 2000 })
//<= 'Volkswagen'
//<= 2000
foo()
//<= エラー
デフォルト値:
function foo({ brand = 'Volkswagen', make = 1999 } = {} ) {
console.log(brand)
console.log(make)
}
foo()
//<= 'Volkswagen'
//<= 2000
残余引数とスプレッド演算子#
- 残余引数
- スプレッド演算子
反復可能なオブジェクトを配列に変換します
[...'show me']
//<- ['s', 'h', 'o', 'w', ' ', 'm', 'e']
テンプレートリテラル#
バッククォート ` を使用して表します:
var text = `Hello "World"`
- 文字列補間
`Hello, ${ 2 + 3 }`
//<- "Hello, 6"
- タグ付きテンプレート
// タグ付きテンプレートの場合
tag`Hello, ${name}. I am ${ emotion } to meet you!`
// 次のような関数呼び出しがあります
tag(
['Hello, ', '. I am ', ' to meet you!'],
'Maurice',
'thrilled'
)
// tag関数の実装方法
function tag(parts, ...values) {
return parts.reduce(
(all, part, index) => all + values[index - 1] + part
)
}
クラス、シンボル、オブジェクトとデコレーター#
クラス#
プロトタイプ
function Fruit(name, calories) {
this.name = name
this.calories = calories
this.pieces = 1
}
Fruit.prototype.chop = function () {
this.pieces++
}
Fruit.prototype.bite = function (person) {
...
}
クラス
class Fruit {
constructor(name, calories) {
this.name = name
this.calories = calories
this.pieces = 1
}
chop() {
this.pieces++
}
bite(person) {
...
}
}
式としてのクラス宣言
const Person = class {
constructor(name) {
this.name = name
}
}
コンストラクタ関数によるクラスの作成
const createPersonClass = name => class extends Person {
constructor() {
super(name)
}
}
const JackePerson = createPersonClass('Jake')
const jake = new JackePerson()
同じキーでデータを保存して読み取るクラス:
class LocalStorage {
constructor(key) {
this.key = key
}
get data() {
return JSON.parse(localStorage.getItem(this.key))
}
set data(data) {
localStorage.setItem(this.key, JSON.stringify(data))
}
}
静的メソッド
// プロトタイプチェーン
function Person() {
...
}
Person.isPerson = function (person) {
return person instanceof Person
}
// クラス
class Person {
...
static isPerson() {
...
}
}
クラスの継承
// プロトタイプ継承
function Banana() {
Fruit.call(this, 'banana', 105)
}
Banana.prototype = Object.create(Fruit.prototype)
Banana.prototype.slice = function() {
...
}
// クラス継承 -> extends キーワードを使用
Object.assign
オブジェクトのマージ操作
function md(input, options) {
const config = Object.assign({}, defaults, options)
}
// defaults が最初に {} に割り当てられ、その後 options が {} に割り当てられます。
// ユーザーが提供したプロパティは上書きされます
Object.assign はオブジェクトを再帰的にコピーしません
Object.assign({}, { a: { b: 'c', d: 'e' } }, { a: { f: 'g' } })
// <- { a: { f: 'g' } }
より優先して使用すべき代入方法:
const grocery = { ...details }
// Object.assign({}, details)
const grocery = { type: 'fruit', ...details }
// Object.assign({ type: 'fruit' }, details)
const grocery = { type: 'fruit', ...details, ...fruit }
// Object.assign({ type: 'fruit' }, details, fruit)
const grocery = { type: 'fruit', ...details, color: 'red' }
// Object.assign({ type: 'fruit' }, details, { color: 'red' })
Object.is
NaN === NaN
// <- false
Object.is(NaN, NaN)
// <- true
-0 === +0
// <- true
Object.is(-0, +0)
// <- false
Object.setPrototypeOf
既存のオブジェクトのプロトタイプを変更しますが、パフォーマンスに問題があります
//ES5
const baseCat = { type: 'cat', legs: 4 }
const cat = Object.create(baseCat)
cat.name = 'Milanesita'
//ES6
const baseCat = { type: 'cat', legs: 4 }
const cat = Object.setPrototypeOf(
{ name: 'Milanesita' },
baseCat
)
シンボル#
プライベートシンボル (ラッピングオブジェクトの作成、参照の保存または反射アクセス)
- シンボルの作成
const first = Symbol('something')
// ユニーク性
console.log(Symbol() === Symbol())
// <- false
console.log(Symbol('my symbol') === Symbol('my symbol'))
// <- false
- オブジェクトのプロパティ名として
const weapon = Symbol('weapon')
const character = {
name: 'Penguin',
[weapon]: 'umbrella'
}
- for...in、Object.keys、Object.getOwnPropertyNames ではシンボルプロパティを取得できません
- Object.getOwnPropertySymbols を使用して取得できます
console.log(Object.getOwnPropertySymbols(character))
// <- [Symbol(weapon)]
シンボルの使用
...
デコレーター#
クラスデコレーター関数は、デコレーションされたクラスのコンストラクタ関数 ctor、デコレーションされたクラスが他のクラスを継承している場合は親クラスの heritage、デコレーションされたクラスのメンバー記述子リストの merbers 配列の 3 つの引数を受け取ります。
イテレーションとフロー制御#
To be write