Can I use
文法
var/let/const
- var - JavaScript | MDN
- HTML4以前のもので、全てのブラウザで使用可能。
- let - JavaScript | MDN
- const - JavaScript | MDN
var, let, constの違い
宣言 | スコープ | 再代入可能 |
---|---|---|
なし | グローバル | ◯ |
var | 関数 | ◯ |
let | ブロック | ◯ |
const | ブロック | ◯ |
varは不要っぽい
以下の理由から、もうvarは不要かと思われます。
- IE11を含む主要ブラウザでサポートされている1。
- ただし、IE11のletは一部問題があるらしい(Can I useより)
- 関数スコープが必要なケースがほとんどない、あっても関数の先頭で宣言すればよい。
this
JavaScriptではthisが呼び出される文脈によって異なっていたためいろいろと問題があった。 解決案は2通り。
- アロー関数を使う
- bindを使う
foo.bind(this, arg1, arg2)
- this - JavaScript | MDN
- Function.prototype.bind() - JavaScript | MDN
- Function.prototype.call() - JavaScript | MDN
bind
- bindの1番目の引数はthisを束縛するもの。nullを指定すると束縛しない。
- bindの2番目以降の引数は関数の引数を束縛する。
アロー関数
Strictモード
使用方法
他のいかなる文よりも先に"use strict";
, または'use strict';
という文をそのまま追加します。
MDNの記事に書かれていますが、 スクリプトの先頭に書くと、webpackなどで連結するときに連結後のスクリプト全体が strictになってしまうので、注意が必要です。 関数ごとに付けるのが安全です。
Strictモードによってエラーになるもの
詳細はMDNの記事にありますが、 注意すべきことは以下になります。
- 8進数が禁止される(間違って使われやすいため)
- with文が禁止される(最適化のため)
eval
で宣言した変数は外部に影響しない
Strictモード宣言はただの文字列なので、 未対応ブラウザには影響しません2。 なので、使ったほうが良いです。
比較演算子
以下のように、==
は曖昧な比較、===
は厳密な比較を行う3。
Equality (==) The equality operator converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
1 == 1 // true
'1' == 1 // true
1 == '1' // true
0 == false // true
0 == null // false
var object1 = {'value': 'key'}, object2 = {'value': 'key'};
object1 == object2 //false
0 == undefined // false
null == undefined // true
Identity / strict equality (===) The identity operator returns true if the operands are strictly equal (see above) with no type conversion.
3 === 3 // true
3 === '3' // false
var object1 = {'value': 'key'}, object2 = {'value': 'key'};
object1 === object2 //false
==
と===
のどちらを使うべきか?
曖昧な比較はバグの元のため、===
を使うことが望ましい4。
if (foo)
とif (foo === bar)
のどちらを使うべきか?
Javaならif (foo)
で決まりなんですが、
JavaScriptではTruthyという「真値っぽい5」判定に使われるので、
なるべくは避けたいところです。
たぶんこんな感じかなぁと。
- 左辺・右辺ともにboolean:
if (foo)
- 左辺・右辺ともにオブジェクト、undefined、nullのみ:
if (foo)
- それ以外:
if (foo === bar)
String
Array
基本操作
要素のループ
以下でいいと思います。
- IE対応が必要な場合: Array.prototype.forEach()
- IE対応が不要な場合: for…of
for...in
は全てのプロパティを反復する(for…of参照)のため、
おそらく意図した挙動ではありません。
最初に見つかった要素を返却
以下でいいと思います。
- IE以外: Array.prototype.find()
- IE: Polyfillを使う6
要素が存在するかどうかをチェック
- 要素指定、boolean: Array.prototype.includes()
- IEでは使用不可
- 要素指定、index: Array.prototype.indexOf()
- コールバック指定、boolean: Array.prototype.some()
NodeListなどから変換
以下のArray.fromがいいと思います(IE以外では動きます)。
Date
昨日の日付を取得する
以下のように、setDate()に日付を1引いたものを与える。
var d = new Date();
d.setDate(d.getDate() - 1);
1日の場合も適切に調節してくれるため問題ない[^setDate]。
dayValue がその月の日付の範囲外の値の場合、 それに応じて setDate() が Date オブジェクトを更新します。 例えば、dayValue に 0 を与えた場合、日付は前月の最終日に設定されます。
Iterator
[Symbol.iterator]
というメソッドを定義する(この構文よく分からん)。
自分で定義することはないと思いますが、 DDDにおけるAggregatesを実装したときに実装すると便利です。
URLのエンコード
- encodeURIは特殊文字をエンコードしない。
- encodeURIComponentは特殊文字をエンコードする。
非同期処理
Promise
値の代わりに返すことができるもの。 たぶん「約束手形」と同じですね。
async/await
Promiseだけだとしっくりこないのですが、async/awaitを使うと楽になります。
非同期にする(Promiseを返す)functionにasyncを付けて、 戻り値を同期にしたいときにawaitを付けるだけなので、楽です。
注意点として、forEachとは相性が悪いことです。 for .. ofを使います。
また、(現在は)トップレベルでも使えません。
ただ、これは簡単な回避方法はあります。即時関数を使用するだけです。
(async () => {
// ここに処理を書く。
})();
Ajax
従来はXMLHttpRequestが使われていましたが、 今後はfetchが使われることになりそうです(polyfillもあります)。
eval
安全なeval
- notevilが一番いいです。
notevilによるevalの実装
たとえば、Moment.jsとsprintfをそのまま使えるようにしたい場合は、 以下のようにします。
const func = safeEval(funcstr, {
moment: function() {
return moment();
},
sprintf: function(...args) {
return sprintf(...args);
}
})
関数の定義の場合は以下のようになります。
safeEval.Function("moment", "sprintf", value['value']).call(this, moment, sprintf);
モジュール
Node.jsでの書き方
module.exportsを使ってこんな感じで書く。
var foo = {
init: function() {
...
}
}
module.exports = foo;
正確には以下のようになるようです。
- デフォルトでは
module.exports
とexports
は同じ module.exports
にオブジェクトを代入すると、exports
は使えない。
参考: Node.jsのexportsについて - 30歳からのプログラミング
ES2015の書き方はどうか?
モジュールはES2015での書き方もありますが、 自分としてはまだ流動的なので、しばらくは使わない予定です。
2017年8月現在なので現状と変わっている可能性はありますが、 現段階ではおすすめしないという記事がありました8。
ブラウザの互換性
- Chrome: submitボタンにonclickを使ってdisabledすると動かない
- Chromeの場合、submitボタン押下時にボタンをdisabledにすると、フォームデータが送信されない。 - Qiita
- フォームに onsubmit()を付ける必要がある。
- Chromeの場合、submitボタン押下時にボタンをdisabledにすると、フォームデータが送信されない。 - Qiita
-
Can I use… Support tables for HTML5, CSS3, etcによれば、主要ブラウザは全て対応しているようですが。 ↩︎
-
検証はしていませんが、いくつか実装が見つかりました。 ↩︎
関連項目
逆引きマニュアル
- JavaScript: 特定のキーを無効にする方法
- JavaScript/DOMで子要素を全て削除する方法
- JavaScriptからTypeScriptへの変換方法(コンパイルを通すまで)
- 【継続調査】JavaScriptでのIMEハンドリング
- JavaScript: script要素のURLからパラメータを取得
- JavaScript: AmazonのページからYAMLを作成する方法
- JavaScript: 任意のページをYAML化
- JavaScript: 日付をフォーマットする
- JavaScript: あるセレクタを持つ要素全てを処理する