はしくれエンジニアもどきのメモ

情報系技術・哲学・デザインなどの勉強メモ・備忘録です。

2日でできる JavaScriptTraining」をやってみた(イディオムと感想)

「2日でできる JavaScriptTraining」をやってみた(イディオムと感想)

mixi の「2日でできる JavaScriptTraining」をやってみたのでメモ。 今回は、ラストのイディオム編です。

github.com

環境

動作したバージョンを以下にに書いておく。

  • 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 を返します。

参考:論理演算子 - JavaScript | MDN

|| で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