2日でできる JavaScriptTraining」をやってみた(イディオムと感想)
「2日でできる JavaScriptTraining」をやってみた(イディオムと感想)
mixi の「2日でできる JavaScriptTraining」をやってみたのでメモ。 今回は、ラストのイディオム編です。
環境
動作したバージョンを以下にに書いておく。
-
Chrome 46.0.2490.86 m (64-bit)
-
Node.js v5.0.0
-
npm 3.4.1
-
gulp version 3.9.0
-
bower 1.6.5
-
-
7.よくあるイディオムを読むトレーニング
クロージャ
下記コードでは、 カウンタ変数i が毎回初期化されるので、 カウントアップされない。
var createCounter = function() {
var i = 0;
return i++;
};
var count = createCounter;
console.log(count()); // 0
console.log(count()); // 0
console.log(count()); // 0
下記コードでは、 var counter = createCounter();
により、 function() { return i++; }
を持つことになる。 なので、上記と違ってカウンタ変数が毎回初期化されることはない。 そして、counter();
を実行することで、 return i++;
によりカウントアップすることができる。
カウンタ変数i は隠蔽されているので、 外部からアクセスできないようになっている。 これがクロージャ。
var createCounter = function() {
var i = 0;
return function() {
return i++;
};
};
var counter = createCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
関数ファクトリ
クロージャで関数ファクトリを作ることができる。
function makeAdder(x) {
return function(y) {
return x + y;
}
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(1)); // 6 と表示される
console.log(add10(1)); // 11 と表示される
真理値演算
JavaScript の真理値演算は、値がbooleanでなくても演算結果を返す。
論理 OR (||) :
expr1 && expr2
: expr1 を true と見ることができる場合は、expr1 を返します。そうでない場合は、expr2 を返します。論理 AND(&&):
expr1 || expr2
: eexpr1 を false と見ることができる場合は、expr1 を返します。そうでない場合は、expr2 を返します。
||
でtrue になる値が代入される。 右辺左辺がともにtrue の場合、 左辺の値になる(左が優先される)。
var foo = 'foo';
var bar = 'bar';
console.log(foo || ''); // foo
console.log(foo || bar); // foo
console.log(bar || foo); // bar
&&
でtはfalse になる値が代入される。 右辺左辺がともにtrue の場合、 右辺の値になる(右が優先される)。
var foo = 'foo';
var bar = 'bar';
console.log(foo && ''); // ''
console.log(foo && bar); // bar
console.log(bar && foo;); // foo
真理値変換
number である0, 1 をBoolean であるfalse, true に変換する。
var truthy = 1;
var falsey = 0;
console.log(!!truthy); // true
console.log(!!fulsey); // false
console.log(Boolean(truthy)); // true
console.log(Boolean(falsey)); // false
闇のJS力
普段使わないけど知っていて損なし系のイディオムメモ。
== 演算子の振る舞い
console.log('10' == 10); //true
console.log(null == undefined); // true
console.log(null == false); // false null とfalse は等しくならない
console.log(true == 1); // true
console.log(true == 10); // false
console.log([0, 1] == 0); // false
console.log([1] == 1); // true
console.log([0] == 0); // true
意図しない true/false
console.log(Boolean(false) ? true : false); //false
console.log(new Boolean(0) ? true : false); //false
console.log('abc' ? true : false); //true
console.log(Boolean(false) ? true : false); //false
console.log(Boolean(false) ? true : false); //false
console.log(Boolean(0) ? true : false); //false
console.log(abc' ? true : false); // true
console.log('' ? true : false); //false
console.log(String(0) ? true : false); // true
console.log(String('') ? true : false); // false 空文字はfalse
console.log(new String(0) ? true : false); // String オブジェクトの生成なので評価はtrue
console.log(new String('') ? true : false); // true
読みづらいキャスト
console.log(10 + ''); // '10' stringになる
console.log(+'10'); // 10 number になる
console.log('10.1'|0); // 10 number 小数部分が無効になる
var obj = { length: 2, 0: 'foo', 1: 'bar' };
console.log(Array.prototype.slice.call(obj)); // ['foo', 'bar'] 長さ2の配列
console.log(+ (new Date())); // number のタイムスタンプ
console.log(typeof +(new Date()); // number
console.log(new Date()); // string の日付
console.log(typeof ((new Date()) + 0)); // string
Array コンストラクタ
console.log(Array(3)); // [,,]
console.log(Array(3)[0]); // 空要素
console.log(Array(3).length); // 3
console.log(Array(1, 2, 3).length); //3
console.log(Array(1, 2, 3)[0]); // 1
console.log(Array(1, 2, 3)); // [1, 2, 3]
console.log();
console.log();
型判定
console.log(typeof 0); // 'number'
console.log(typeof true); // 'boolean'
console.log(typeof 'string'); // 'string'
console.log(typeof function() {}); // 'function'
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object' 配列もobjectになる
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' nullはobject
感想
「2日でできる JavaScriptTraining」をやってみて、 以下の学びを得た。
-
Node.js にちょっと慣れた。
-
配列を見たら、
.forEach
.map
,.reduce
,.filter
の関数型っぽい関数が使えるか疑う。 -
非同期通信では、バニラJSでも Fetch API でシンプルに使える。
-
(非同期通信での)Promiseの使い方
-
フロントエンド系モジュールシステムのbowerの使い方
saga1 からWebComponents を使っていたりで レベル高く面白かった。
個人的には、map, reduce
系は あまり使ったことがなかったので、項目としてあっても よかったかなと思った。
bower は、dotinstallさんにも無かったので良い学びになった。(npm がこれからフロントエンド系も扱うので bower から新規パッケージが減るんじゃないかと話もあるみたいですが。。)
従来のJavaScript でのオブジェクト志向 とES6 でのオブジェクト志向(class)の話もあれば、 ほぼJavaScriptを網羅できるんじゃないかと思いました。
open にドキュメントを提供してくださってるmixi さんありがとうございます。
そろそろ CoffeeScript やTypeScirpt などの AltJS に手を出そうと思います。
参考リンク