文字列リテラル
HTMLを含む文字列を生成する際に便利なため、囲む時はシングルクォート'hoge'
がよい
セミコロン
末尾にセミコロンをつけなくても解釈してくれるが、バグを生む可能性があるのでセミコロンはつけるように習慣化する
ES6のclass記法のメソッド末尾にはセミコロン不要
同値比較
基本的に===
をつかう。==
だと寛容過ぎる解釈のため、バグを生むことがある。
短絡評価
hogeFuncの引数にtrue相当の値が入ってきた場合、
||
の右側は読まれない。
hogeFuncの引数にfalse相当の値が入ってきた場合、
(false
, null
, undefined
, NaN
, ""
, 0
)
||
の右側を読みにいく。
function hogeFunc(e){
e || console.log('piyo');
}
hogeFunc(1); // 何も出力されない。もし短絡評価がなければ右側も評価されるのでpiyoが出力される
hogeFunc(); // piyoが出力される
こういう使い方も
function hogeFunc(e){
var hoge = e || 1;
console.log(hoge);
}
hogeFunc(5); // 5
hogeFunc(); // 1
for文
for(let i = 0, j = 0; i < 3; i++, j+=2){ // カンマで複数追加もできる
console.log(i,j);
}
for...in
はインデックス番号やキー名を取り出すだけなので、連想配列やオブジェクトを走査するときだけに使う。不便。
[追記] 20160808
「for...in列挙遅すぎ問題」「prototype汚染列挙問題」等が存在しますので、現代的なJavaScriptにおいてはそもそも for...in 自体を使わない方が安全です。
一方、ES6のfor...of
は値を返してくれるので便利。
Array.prototype.keys()
とArray.prototype.entries()
も使えばもっと便利
let arr1 = ['a','b'];
let arr2 = ['あ','い','う'];
// ...iterable
// イテラブルなオブジェクトの値を順次取り出す
let margeArr = [...arr1, ...arr2]; // 配列の結合もできる
for(let val of margeArr){
console.log(val);
// "a"
// "b"
// "あ"
// "い"
// "う"
}
for(let val of margeArr.keys()){
console.log(val);
// 0
// 1
// 2
// 3
// 4
}
for(let [i, val] of margeArr.entries()){
console.log(i, val);
// 0 "a"
// 1 "b"
// 2 "あ"
// 3 "い"
// 4 "う"
}
配列操作の詳細はこちら
http://qiita.com/mo4_9/items/2968fea172c028d58aec
型
|型|具体例|引数の渡し方|
|---|---|---|---|
|プリミティブ|boolean, number, string, symbol(ES6), null, undefined|値渡し|
|その他|object|参照渡し|
プリミティブ型
-
boolean, number, string, symbol(ES6)
オブジェクトとして振舞おうとした際に、バックグラウンドでそれぞれの型に応じたラッパーオブジェクトが生成される。
(ちなみにES6からプリミティブ型の明示的なラッパーオブジェクトの作成はサポートされなくなった為、Symbolはnewできない) -
null, undefined
ラッパーオブジェクトなし。常にプリミティブ型。
null と undefined の違い
null
はエンジニアが意図的にセットしないと出会すことはない。
undefined
はエンジニアのミスで発生する。
初心者はざっくりと上記の認識でok
あとは以下のような地雷を踏んだとき、その都度覚えていけばいい
// #hogeがDOMに存在しない状態で
console.log( document.getElementById('hoge') ); // null
console.log( 'hoge'.match(/a/) ); // null
null
:定義済み(存在している)だが、値や型がない
undefined
:未定義(存在していない)
参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/null
型変換
-(マイナス)
は数値演算子にしかないので、Stringの'1'
に- 0
すると'1'
がNumberに暗黙で型変換(キャスト)される。+(プラス)
はStringの連結にも使うのでNumberへの型変換はおこなわれない。
'1' - 0 // 1 (Number)
'1' + 0 // '10' (String)
しかし上記はパッと見わかりにくいので、使わないほうがいい。
代替案としてparseInt()
とNumber()
さらにparseInt()
のほうが柔軟に処理してくれるので便利と言える
parseInt('1') // 1
parseInt('1px') // 1
Number('1') // 1
Number('1px') // NaN -> Not-A-Numberの略でnumber型
参考
型変換のいろいろ
JSON
ごちゃっとしたデータはJSONにまとめる
変換ツール
http://shancarter.github.io/mr-data-converter/
整形ツール
https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh
関数
JavaScriptにおける関数は第一級オブジェクトである。
型は「 [[Call]] を持つ Object 型 」であり、関数型は存在しない。
参考
まさに忍者...JavaScriptの関数は第一級オブジェクト
12.5.6 The typeof Operator – ECMA-262 6th Edition
即時関数
!
を先頭につけるとシンプルになる。小ネタ。
!function hoge() {
console.log('hoge');
}();
ES6からはブロックスコープのマスキングが不要だったりするので使用頻度は減りそうだが、以下のようなケースでは使用する必要あり。
・名前付き関数式で再帰呼び出し
・Function.prototype.call() で this 値を変更
'use strict';
(function () {
console.log(this);
}.call(this));
参考
Function.prototype.call()
JavaScript, 即時関数でthisを指定して引数も受け取る
ES2015(ES6)新構文:アロー関数(Arrow function)
ES2015(ES6)の即時関数は短く書けるしletならそもそも不要
Class
クラス名 -> 名詞
メソッド名 -> 動詞
なるべく細かく外部ファイルに切り分ける
1ファイル100行以内くらいが理想
new演算子
オブジェクトのインスタンスを返却しなさい!とコンストラクタに命令する演算子。
自動的にreturn
しているということ。
this
class class1 {
func1(){
// ここでのthis=class1オブジェクト
const self = this;
img.addEventListener('load', function(){
// ここでのthis=img
}, false);
}
}
argumentsオブジェクト
関数呼び出しの際に引数のチェックがないのでargumentsオブジェクトで管理する。
ES6だと可変長引数を容易に配列に格納できる。
function f(x, ...aiu) {
console.log(x, aiu); // 1 ["a", "i", "u"]
// 引数の値を取得
for(let i = 0; i < arguments.length; i++){
console.log(arguments[i]);
}
// エラーハンドリング
if(arguments.length != 2){
throw new Error('引数の数が不正です');
}
// 可変長引数の値を取得
for(let arg of aiu){
console.log(arg);
}
}
f(1, 'a', 'i', 'u');
引数が多い場合は、引数に名前をつけるとわかりやすい
function person(opts = {}){ // 初期値の設定
const name = opts.name;
const age = opts.age;
console.log(name,age);
}
person ({
name:'bob',
age:30
});
※ES6前提なら可変長引数だけで十分。argumentsは不要。
bind
thisを束縛する
function sum (val1,val2){
console.log(this.val + val1 + val2);
}
let obj1 = {val: 1};
let obj2 = {val: 2};
let obj1Sum = sum.bind(obj1); // thisだけを指定
let obj2Sum = sum.bind(obj2,2,2); // thisと引数を指定
obj1Sum(1,1); // 3
obj2Sum(); // 6
thisをnullにして、引数のみを束縛する
function sum(x,y,z){
console.log(x+y+z);
}
let sumA = sum.bind(null,1);
sumA(2,3); // 6
get / set
functionの部分をget/setにする
let human = (() => {
let _name;
return { // クロージャ
get name(){
return `名前は${_name}です`;
},
set name(val){
_name = val;
}
}
})(); // 即時実行
human.name = 'steve';
human._name = 'jobs';
console.log(human.name);
console.log(human._name);
Ajax
Ajax通信
Deferred
イベント
イベントの伝播
カスタムイベント
クロージャ