4
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScript再入門

Last updated at Posted at 2018-01-11

クォーテーションはシングル?ダブル?

違いはないよう。
シングルを採用することの方が多い。

関数?メソッド?

オブジェクトのプロパティはメソッド。
そうでないものは関数。
のよう。

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

外部モジュール等から、関数、オブジェクト、プリミティブをエクスポート、インポートするために使用。

名前付きエクスポートとインポート

my-module.js
function hoge() {...};
const fuga = 1;

export {hoge, fuga};
import {hoge, fuga} from 'my-module';

console.log(hoge());
console.log(fuga);

デフォルトエクスポートとインポート

インポート時に特に指定がなければ、デフォルトエクスポートの値が呼ばれる。

my-module.js
export default function() {...};
import hoge from 'my-module';

console.log(hoge());
4
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?