KMC活動ブログ

京大マイコンクラブの活動の様子を紹介します!!

ECMAScript6勉強会 第8回・第9回・第10回

おはようございます。id:tyageです

9/1に第8回を、9/9に第9回を、9/15に第10回を行いました。

第8回

この回では template string, tagged template string, octal literals, binary literals の部分を読みました。

ちなみにこの日はKMCのコーディング合宿が行われたため、合宿所にて行いました。

template string

「`」でくくることで、以下の様なテンプレート文字列を利用することが可能になりました。

また、${ expression } とすれば、JavaScriptの式を書くことができます。

name = 'world'
console.log(`hello ${name}`) // => 'hello world'

「`」内であれば改行することも可能なので、htmlのテンプレートも書きやすくなりました。

template = `
<div>
  <p>1 + 1 = ${1 + 1}</p>
</div>
`

ちなみにfirefox 35では使えるようになっています。

おかげで文字列操作がかなり便利になりました。

今後はこれを利用したtemplate engineが出てくるとは思いますが、どうなるのか楽しみです。

tagged template string

上記で出てきたtemplate stringを、callSiteとexpression部分にわけて関数に渡すことができます。

function tag(strings, ...values) {
  console.log(strings) // => [ "", " vs ", "" ]
  console.log(values) // => [ 33, 4 ]
}
tag`${ 33 } vs ${ 4 }`

()をつけなくても関数呼び出しができてしまうので、少々わかりにくい気がしますが、i18nライブラリが作りやすくなる等、一部で便利な記法だと思います。

octal literals, binary literals

0xdeadbeafのような hex literalsの他に、8進数表記の octal literals、2進数表記の binary literalsが増えました。

0o01234567 // => 342391
0b10101010 // => 170

octal literalsだと大文字のOを利用して、0O0000みたいな表記もできるのですが見づらいですね...

第9回

この回では const, for..of loops, rest parameters, spread call (...) operator, spread array (...) operator, string spreading を読みました

const

ES6ではconstが使えるようになりました。

const a = 1
a = 2
console.log(a) // => 1

内部的にはIsConstantDeclarationがtrueになり、CreateImmutableBindingが呼ばれるようです。

for..of loops

for .. ofはiterableなオブジェクトをループする新しい構文です。

for (let a of [3,3,4]) {
  console.log(a)
}

let m = new Map([['H', 4], ['C', 33]])
for (let [name, value] of m) {
  console.log(`${name} = ${value}`)
}

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-bindinginstantiationでは

ForDeclaration : LetOrConst ForBinding

1. For each element name of the BoundNames of ForBinding do
  a. If IsConstantDeclaration of LetOrConst is true, then
    i. Call environment’s CreateImmutableBinding concrete method with argument name.
  b. Else,
    i. Call environment’s CreateMutableBinding concrete method with argument name.
    ii. Assert: The above call to CreateMutableBinding will never return an abrupt completion.
2. Return the result of performing BindingInitialization for ForBinding passing value and environment as the arguments.

とあるので、letの代わりにconstも利用できるようにみえるのですが、firefox 35.0a2ではsyntax errorが出てしまいました。

rest parameters, spread call (...) operator, spread array (...) operator, string spreading

...キーワードを使ってiterableなオブジェクトを展開したり、配列として残りの引数をまとめて受け取ったりできるようになりました。

また ..."string" とすることで文字を1文字ずつ分解することもできるようになりました。

// rest parameters
foo = (a, b, ...rest) => console.log(rest)
foo(1, 2, 3, 4, 5) // => [3, 4, 5]

// spread call operator
// Math.max(2, 3, 1, 2, 3, 1, 2, 4, 6, 7, 1) と同じ
Math.max(2, 3, ...[1, 2, 3], 1, 2, ...[4,6,7], 1) // => 7

// spread array operator
[2, 3, ...[1, 2, 3], 1, 2, ...[4,6,7], 1] // => [2, 3, 1, 2, 3, 1, 2, 4, 6, 7, 1]
[...(new Set([1, 2, 3]))]

// string spreading
[1, ..."hoge", ...[1,2,3]] // => [ 1, "h", "o", "g", "e", 1, 2, 3 ]

いままで arguments オブジェクトを使って処理していた可変長引数が扱いやすくなりました。

第10回

この回では Number.*, String.raw, String.fromCodePoint, String.prototype.codePointAt を読みました

Number.*

Numberオブジェクトに追加されたメソッド・プロパティを確認しました

具体的には、Number.isFinite, Number.isInteger, Number.isSafeInteger, Number.isNaN, Number.EPSILON, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER です。

// Number.isFinite
Number.isFinite(1) // => true
Number.isFinite(1/0) // => false
Number.isFinite(0xfffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) // => true
Number.isFinite(0xfffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) // => false

// Number.isInteger
// 内部的にはToIntegerした結果と一緒ならtrue, 異なればfalse
Number.isInteger(3) // => true
Number.isInteger(Infinity) // => false
Number.isInteger(0.1) // => false

// Number.isSafeInteger
// 絶対値が2^53 - 1の範囲内であればtrue
Number.isSafeInteger(Math.pow(2,53)-1) // => true
Number.isSafeInteger(Math.pow(2,53)) // => false

// その他
Number.isNaN(NaN) // => true
Number.EPSILON // => 2.2204460492503130808472633361816 x 10<200d>^−<200d>16
Number.MIN_SAFE_INTEGER // => -9007199254740991
Number.MAX_SAFE_INTEGER // => 9007199254740991

String.raw

template stringのrawを参照できます

`foo\n` // => foo
String.raw`foo\n` // => foo\n
`foo\n`.length // => 4
String.raw`foo\n`.length // => 5
String.raw`foo${1+2}` // => foo5
`\x31` // => 1
String.raw`\x31` // => \x31

tagged template stringを利用しているので、以下のようにすればtemplate string以外のオブジェクトも渡すことができます

console.log(String.raw({ raw: ["a", "b", "c"] }, 0, 1, 2, 3)) // => "a0b1c"

String.fromCodePoint, String.prototype.codePointAt

String.fromCharCode, String.charCodeAtと異なり、utf-16エンコードされます。

以下に、🍣(寿司の絵文字)を扱った例を示します

console.log(String.fromCharCode(0xd83c, 0xdf63)) // => "🍣"
var utf16Sushi = Math.pow(2, 16) + (0xd83c - 0xd800) * Math.pow(2, 10) + (0xdf63 - 0xdc00)
console.log(utf16Sushi.toString(16)) // => "1f363"
console.log(String.fromCodePoint(utf16Sushi)) // => "🍣"
console.log("🍣".codePointAt(0).toString(16)) // => "1f363"
console.log("🍣".codePointAt(1).toString(16)) // => "df63"

次回(第11回は)10/6に行われます。