JavaScrip、自分用メモ

Contents

最近、 javascriptをガンガンやっているので、その時のメモ。



JavaScriptの主なデータ型


基本型 互いに別物 - 数値型(number) - 文字列型(string) - 真偽型(boolean) - シンボル型(symbol) - 特殊型(null/undefined)

参照型 互いに同じ場所を見てる - 配列(array) - オブジェクト(object) - 関数(function)





個々のデータの呼び方


配列内 → 要素

オブジェクト → プロパティ

関数 → メソッド





undefinedとnull


undefinedは変数の値が定義されてないことを表す値

nullは空であるという状態を表すための値

⚠️ 実際のアプリ開発でバグの原因になることも多い。

ex1)

バックエンドをrubyで実装している例。

nameの返り値がundefinedの場合、

rubyはfalse

同じくnameの返り値がnullの場合は

rubyはtrue

name = params[:name] == '' ? nil : User.find(params[:name]).name





値の比較ではなるべく===演算子を使う


==演算子はなんとか等しいと見なせないかとJSがあれこれ努力してくれる演算子なので、値の比較はなるべく===演算子を使う。





falsyな値


JSでは、以下の値も暗黙的なfalseと見なされる。

  • 空文字列(“”)

  • 数値の0、NaN(Not a Number)

  • null、undefined

上記以外の値はすべてがtrueとみなされます。





例外処理 try…catch…finally命令


try {
    例外が発生するかもしれない命令(群)
} catch(例外情報を受け取る変数) {
    例外が発生した時に実行される命令(群)
} finally {
    例外の有無にかかわらず、最終的に実行される命令(群)
}

finalllyはrubyのensureに似てる





組込みオブジェクト


JSでオブジェクトを利用するためには、インスタンス化しなければならないが、JSでは、リテラルをそのまま対応する組込みオブジェクトとして利用できるので、インスタンス化をほとんど意識することがない。





基本データ型をnew演算子を使ってインスタンス化するのは、原則禁止






配列 Arrayオブジェクト


const ary = []; // 空の配列を生成





オブジェクトリテラル


オブジェクトリテラルは{}を書くことで、新しいオブジェクトを作成できます。オブジェクトリテラルはオブジェクトの作成と同時に中身を定義できます。 オブジェクトのキーと値を:で区切ったものを {} の中に書くことで作成と初期化が同時に行えます。

const object = {}; // 中身が空のオブジェクトを作成

const object = {
    key: "value"
};

オブジェクトのkeyの参照方法

// ドット記法

console.log(object.key); // => “value”

// ブラケット記法

console.log(object[“key”]); // => “value”





スタックとキュー


スタック(Stack)

後入れ先出し(LIFO: Last In First Out)のデータ構造。アプリの操作履歴を保存し、最後に実行した操作をまず取りだすみたいな用途で使われる。

push、popメソッドで実装できます。

キュー(Queue)

先入れ先出し(FIFO: First In First Out)。最初に入った要素を最初に処理する。食品の陳列に似てる。

push、shiftメソッドで実装できます。





function命令(関数宣言) と関数リテラル(関数式)


• function命令(関数宣言) → 関数getTriangleを直接定義している

• 関数リテラル → 「function (base, height) {…}」と名前のない関数を定義したうえで、変数getTriangle に格納している。

関数リテラルは、宣言した時点では、名前を持たないことから匿名関数、または無名関数と呼ばれる。

// function命令
function getTriangle(base, height) {
  return base * height / 2
}
console.log('三角形の面積:' + getTriangle(5, 2));

// 関数宣言では"関数名"は省略できない
function 関数名() {
}
// 関数リテラル
const getTriangle = function (base, height) {
  return base * height / 2;
};
console.log('三角形の面積:' + getTriangle(5, 2));

// 関数式は変数名で参照できるため、"関数名"を省略できる
const 変数名 = function() {
};





アロー関数


構文

(引数,...) => { ...関数の本体... }
const getTriangle = (base, height) => {
    return base * height / 2;
}
console.log('三角形の面積:' + getTriangle(5, 2));

引数がない場合でも()を省略することはできない。()には関数を事項するという意味も持っているから。





letのスコープ


varだとブロックレベルのスコープが存在せず、ブロックを抜けたあとでも変数iが有効であり続ける。

if (true) {
  var i = 5;
}

console.log(i); // => 5

letだとブロックスコープに対応した変数を宣言できる。

if (true) {
  let i = 5;
}

console.log(i); // => error





「…」演算子の引数の展開


「…」演算子は、実引数で利用することで、for ...ofブロックで処理できるオブジェクトを個々の値に展開できます。

console.log(Math.max(...[15, -3, 78, 1])); //78





分割代入


代入先の変数もブランケットでくくっているのがポイント。

let data = [56, 64, 94, 89];
let [x0, x1, x2, x3] = data

console.log(x0); // 56
console.log(x3); //89





クラスではなくプロトタイプ


最もシンプルなクラス。

変数Memberに対して、空の関数リテラルを代入しているだけだが、これがJavaScriptのクラス。

var Member = function() {};

このMemberクラスをインスタンス化するにはnew演算子使う。

var menm = new Member();

JavaScriptの世界では、「いわゆる厳密な意味でのクラス」という概念は存在しない。

JavaScriptでは関数(Functionオブジェクト)にクラスとしての役割を与えてる。





縛りの弱いクラス


同一のクラスを元に生成されたインスタンスであっても、それぞれが持つメンバーは同一であるとは限らない





ノードウォーキング


DOMで、あるノードを基点として、相対的な位置関係からノードを取得すること。





onxxxxプロパティによるインベントハンドラーの問題


同一の要素/同一のイベントに対して、複数のイベントがハンドラーを紐付けられない。

同一要素の同一イベントに対して複数紐づけられるのはイベントリスナー

addEventlistenerメソッド

elem.addEventlistener(type, listener, capture)
  elem: 要素オブジェクト    type: イベントの種類
  lister: イベントに応じて実行すべき処理  capture: イベントの方向

• onloadイベントハンドラー → コンテンツ本体と全ての画像がロードされたところで実行

• DOMContentLoadedインベント → コンテンツ本体がロードされたところで実行(=画像のロードを待たない)

ページの初期化処理は、DOMContentLoadedイベントリスナーで表すのが基本





HTML文字列を埋め込む


HTML文字列を埋め込む必要がない場合は、まずtextContentプロパティを優先して利用する。





用語


コンストラクター

(インスタンス)オブジェクトを初期化するメソッドのこと。コンストラクターの名前は、普通の(=コンストラクタでない)関数と区別するために大文字で始めるのが一般的です。

コンストラクターに戻り値は不要

const Member = function (fistName, lastName) {
  // thisはコンストラクターによって生成されるインスタンス(つまり、自分自身)
  // thisに対して変数を指定することで、インスタンスのプロパティを設定できる
  this.firstName = fistName;
  this.lastName = lastName;
  // getNameプロパティに関数リテラルを渡して、getNameメソッド的にを宣言
  this.getName = function () {
    return this.lastName + '' + this.firstName;
  }
};
let mem = new Member('tarou', 'tanaka');
console.log(mem.getName());

プロパティの定義

this.プロパティ名 = 値;

JavaScriptにおいては、厳密にはメソッドという独立概念はなく、値が関数オブジェクトであるプロパティがメソッドとして見なされる

throw命令

構文

throw new Error(エラーメッセージ)

高階関数

関数を引数、戻り値として扱う関数のこと

thisキーワード

  • thisはスクリプトのどこからでも参照できる特別な変数

  • 呼び出す場所、文脈によって中身が変化する

場所 thisの参照先
トップレベル(関数の外) グローバルオブジェクト
関数 グローバルオブジェクト(strictモードではundefined)
call/ applyメソッド 引数で指定されたオブジェクト
イベントリスナー イベントの発生元
コンストラクター 生成したインスタンス
メソッド 呼び出し元のオブジェクト(=レシーバーオブジェクト)

プロトタイプチェーン

プロトタイプにインスタンスを設定るすることで、インスタンス同士を「暗黙の参照」で連結し、互いに継承関係を持たせること。

イベントハンドラー、イベントリスナー

イベントに対してその処理内容を定義するコードの塊(関数)のこと。





参考 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

See Also