クォーテーションはシングル?ダブル?
違いはないよう。
シングルを採用することの方が多い。
関数?メソッド?
オブジェクトのプロパティはメソッド。
そうでないものは関数。
のよう。
obj.hoge(); // (オブジェクトの)メソッド
hoge(); // 関数
セミコロンがあったりなかったりする
なくても動く。
が、絶対つけた方がいい。
書き方によっては、誤訳する可能性あり?
文字列の結合は
様々な言語を触っていると、つい忘れがちなのでメモ。
「+」 でつなげるのが一番いい。
参考:文字列の結合方法による速度差
スコープについて
ブロックスコープはない
var i = 1;
for (i = 0; i<4; i++) {
}
console.log(i); // 4
ただし、下記のletで実現が可能。
関数スコープ
関数の中で定義された変数は、その中でしか参照できない。
ただし関数がネストしている場合、
子の関数は親の関数の変数を参照できる。
var、let、const
varとletはスコープの違い。
varは関数スコープ、letはブロックスコープ。
理由がない限り、letを使っていく方が良い。
constは名前の通り、定数。ブロックスコープ。
ただし、オブジェクトのkeyは保護されないので、全くの不変ではない。
const HOGE = { key: 1 };
HOGE.key = 2; // これはできてしまう
レキシカル?
評価のたびに変わるものではなく、定義時に決まるもの。
静的なものと言えるかもしれない。
グローバルオブジェクト
JavaScriptのコードはオブジェクトに格納されていなければならない。
ので、
何かコードを書けば、実はそれはグローバルオブジェクトに格納された扱いになる。
ブラウザならそれは「window」だし、
node.jsの場合は「global」になる。
strictモード
いくつかの機能を制限することで、厳密なコードが書ける。
どんどん使った方がいい。
スクリプト単位、関数単位で書けるが、
スクリプト単位だと連結等で弊害があるかもしれないので、「関数単位」が良い。
function hoge() {
'use strict'; // 必ず最初に
...
}
strictモードは
・エラーではないが、落とし穴になるようなコードはエラーに
・最適化が困難なものを修正
・将来的なキーワードなどは禁止
といったことを保証してくれる模様。
NaN、undefined、null
説明 | 判別方法 | 備考 | |
---|---|---|---|
NaN | 非数 (結果の存在しない演算結果) |
isNaN(NaN) | |
undefined | 何もない状態 | ES5以降: (x === undefined) ES5以前: (typeof x === 'undefined') |
returnしない関数はundefinedを返す |
null | 返すものがない | (null === null) |
条件文等の判定について
参考:[JavaScript] null とか undefined とか 0 とか 空文字('') とか false とかの判定について
nullやundefinedを同時に処理したいなら
if (hoge) {
のような書き方もできる。
しかし上記の場合、空文字、0、falseも条件に入らなくなるので注意。
eval
文字列をJavaScriptの式として評価する。
eval("2+2");
thisが参照するもの
thisを書いた場所 | 参照するもの |
---|---|
グローバル | グローバルオブジェクト |
単純な関数内(非strict) | グローバルオブジェクト |
単純な関数内(strict) | undefined |
アロー関数内 | 関数の外のthis |
オブジェクトのメソッド内 | そのオブジェクト |
コンストラクタ | そのオブジェクト |
bind
オブジェクト内に単純な関数が記載されていた場合、
その呼び出し方によってthisの内容が異なる。
そんな場合にはbindを使ってthisを拘束できる。
var hoge = {
fuga: function () {
return this;
}
};
hoge.fuga(); // オブジェクトのthisなので、thisはオブジェクト自身となりhogeになる
var myFuga1 = hoge.fuga;
myFuga1(); // myFugaはただの関数になるので、thisがグローバルオブジェクト
var myFuga2 = myFuga1.bind(hoge);// hogeをthisとして拘束
myFuga2(); // thisはhoge
引数の型や数について
JavaScriptの引数は、
・型をチェックしない
→typeof演算子を使う
・引数の数をチェックしない
→引数が足りない場合は未定義、多い場合は無視される
・関数の呼び出しに使う引数は任意の数で良い(定義を気にしなくて良い)
argumentsオブジェクト
関数はargumentsという配列のようなオブジェクトを参照できる。
動的引数などに使える。
let func = function (x) {
console.log(x);
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
};
func(2,3,4); // 2234
デフォルトの引数
function hoge(a, b = 1) {
return a + b;
}
hoge(2); // 3
アロー関数
単純な関数を省略した記載方法。
thisやargumentsを拘束しないという効果もある。
() => {...}
// ↑
// 同じ
// ↓
function () {...}
もっと短縮する
・仮引数が存在する場合、引数を囲む括弧は省略できる
・処理がreturnの一文で済む場合、ブロックとreturnは省略できる
・短縮構文でオブジェクトリテラルを返す場合は、括弧で囲む必要がある
(x) => { return x; }
// ↑
// 同じ
// ↓
x => x;
var func1 = x => { key: x };
func1(1); // undefined
var func2 = x => ({ key: x }); // これが正しい
レスト引数
アロー関数内でargumentsは使えない模様。
ので、レスト引数で対応すれば良い。
(...args) => {
console.log(args);
}
class
クラスを定義する方法は、class文(宣言)とclass式の二つがある。
どちらもstrictモードで実行される。
class文
構文
class MyClass [extends] {
}
class MyClass extends BaseClass {
constructor () {
// super()は親クラスのコンストラクタ
// コンストラクタ内でのみ使える(thisの使用前に呼ぶ必要がある)
super();
this.name = 'Takashi';
}
}
静的メソッド
静的メソッドはインスタンス化しなくても呼ぶことが可能だが、インスタンス化していると呼べない。
class MyClass {
static hoge () {
...
}
}
MyClass.hoge();
クラス変数
ES6だとできないらしい。
以下のような感じでやるしかない。
class Hoge {
constructor() {
this.hoge = 1;
}
}
class式
class式は
・クラス名を省略できる
・再定義、再宣言ができる
・型エラーをスローしない
・typeofはfunctionを返す
構文
var myClass = class [className] [extends] {...};
var Hoge = class {
constructor () {}
one () { return 1; }
};
var hoge = new Hoge();
hoge.one();
var Hoge = class NamedHoge () {
constructor () {}
one () { return NamedHoge.name; }
}
Function
call、apply
参考:Javascriptのcall/apply関数のプロっぽい使い方 〜 JSおくのほそ道 #014
例えば、二つの配列をマージしたいけど、
Array.prototype.pushの引数に配列は渡せない。
いくつかやり方はあるけど、普通の脳内だとループは免れない。
let hoge = [1, 2, 3];
let fuga = [4, 5, 6];
fuga.forEach(value => { hoge.push(value); });
けどそんなの美しくない。
そんな時に↓
let hoge = [1, 2, 3];
let fuga = [4, 5, 6];
// hogeに対して、fuga配列を引数としてpushを実行するよー
Array.prototype.push.apply(hoge, fuga);
上記例は以下を実行しているイメージ。
let hoge = [1, 2, 3];
hoge.push(4, 5, 6);
配列で渡せないなら、applyの引数に配列を渡すという仕様を利用しようジャマイカ。
ということだ。
Object
もの。
プロパティを持つことで、様々な性質を持つオブジェクトとして表現できる。
連想配列として使える。
生成
var obj = new Object();
var obj = {[key1: value1, [key2: value2]...]};
関数も定義できる。
プロパティへのアクセス
var obj = new Object();
obj.hoge = 0;
obj['hoge'] = 1;
Getter、Setter
カプセル化や、追加処理を書いたりできる。
var obj = {
hoge: '',
get hoge() {
return this.hoge;
},
set hoge(val) {
this.hoge = val;
}
};
実装されていないgetter、ないしsetterにはアクセスできない(エラーが発生)
プロパティの削除
delete obj.hoge;
ループで順番にアクセス
for (val in obj) {
・・・
}
Object.keys(obj).forEach(key => {
console.log(obj[key]);
});
コンストラクタメソッド
使いそうなものを抜粋。
メソッド | 説明 | |
---|---|---|
Object.assign(target, ...sources) | targetにsourcesをコピーした結果を返す | |
Object.keys(obj) | プロパティのkeyを、文字列の配列で返す | key配列を取得してそれでループとかよくする |
Object.values(obj) | プロパティの値を、配列で返す |
instanceof
オブジェクトが自身のプロトタイプに、コンストラクタのprototypeオブジェクトを持っているか。
var obj = {...};
if (obj instanceof Obj) {
...
}
Array
配列のこと。
生成
var arr = [];
var num = [1, 2];
要素の取得
var num = [1, 2];
var zero = num[0]; // 1
要素数を知りたい
var len = arr.length;
ループで順番にアクセス
for
let arr = [1, 2];
for (let i= 0; i < arr.length; i++) {
...
}
for in
配列のkeyを抽出。
let arr = [1, 2];
for (let index in arr) {
console.log(arr[index]);
}
for of
配列の値を抽出。
let arr = [1, 2];
for (let val of arr) {
console.log(val);
}
Array.forEach
let arr = [1, 2];
arr.forEach((element, index, thisArr) => {
// elementは処理中の要素
// indexは処理中の要素番号(省略可)
// thisArrは処理対象の配列自身(省略可)
});
forEachでbreakとかcontinueしたい
〜したい | 方法 | 備考 |
---|---|---|
breakしたい | arr.some使え | someは、引数に指定したcallbackでtrueを返せば即座に処理終了する |
continueしたい | returnを書く | |
returnしたい | 無理 |
メソッド
メソッド | 説明 | 備考 |
---|---|---|
arr.filter(() => {...}) | callbackがtrueを返した要素のみで構成された配列を生成し、返す。 | |
arr.find((element, index, thisArr) => {...}) | callbackが真を返した要素をすぐに返す 見つからなければundefind。 |
|
arr.findIndex((element, index, thisArr) => {...}) | callbackが真を返した要素のインデックスをすぐに返す 見つからなければ-1。 |
|
arr.includes(search) | 特定の要素が含まれているか調べ、booleanで返す。 | |
arr.indexOf(search) | 特定の要素が含まれているか調べ、最初の要素のインデックスを返す。 見つからなければ-1。 |
|
arr.reduce((pre, element, index, thisArr) => {...}) | callbackが返した結果をpreに累積する | |
arr.map((element, index, thisArr) => {...}) | callbackで返した値を配列に詰めて、結果に返す | |
arr.slice(begin[, end]) | インデックスbeginから、インデックスendの手前まで返す | |
srr.some((element, index, thisArr) => {...}) | callbackで返した値がtrueなら即座にtrueを返してくれる |
JSON
メソッド
メソッド | 説明 |
---|---|
JSON.parse(str) | strを解析して、JSONに相当するObjectを返す |
JSON.stringfy(js_value) | JavaScriptの値を、JSON文字列に変換して返す |
prototype
継承元のオブジェクトみたいなもの。
継承先のオブジェクトは、暗黙の参照が可能となる。
メソッドの共通化などに用いられる。
var Man = function () { this.name = ''; };
var Takashi = new Man();
Man.prototype.help = function () { alert('help!!'); };
Takashi.help(); // help!!
正規表現
try...catch
try {
// throw '好きな文字列';
} catch(e) {
// eは例外オブジェクト
} finally {
...
}
exportとimport
外部モジュール等から、関数、オブジェクト、プリミティブをエクスポート、インポートするために使用。
名前付きエクスポートとインポート
function hoge() {...};
const fuga = 1;
export {hoge, fuga};
import {hoge, fuga} from 'my-module';
console.log(hoge());
console.log(fuga);
デフォルトエクスポートとインポート
インポート時に特に指定がなければ、デフォルトエクスポートの値が呼ばれる。
export default function() {...};
import hoge from 'my-module';
console.log(hoge());