JavaScript
Node
api

『JavaScript: The Good Parts』で紹介されている標準メソッドまとめ

More than 3 years have passed since last update.

『JavaScript: The Good Parts』で紹介されている標準メソッドまとめ

JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティスは、JavaScriptの「良いパーツ」のみを厳選した、JavaScriptを書く人なら一度は読んでおきたい
良書です。したがって、ここで紹介されている標準メソッドは、積極的に取り入れるべきメソッドです。

「車輪の再発明はするな」とはよく言われることですが、標準APIに詳しくなることで普段書くJavaScriptもかなりきれいにまとまって書けるようになります。
本記事では省いているRegExpやNumberの節、または標準メソッド以外のJavaScriptの「良いパーツ」に興味が出た方は、一度本書を手にとって見てみてください。

「JavaScriptは言わばひとかたまりの大理石であり、私はその中からこの言語のすばらしい本質が現れるまで、美しくない機能を取り除いていく。最終的に私が削り出すことになる美しいサブセットは、より信頼でき、読みやすく、メンテナンスがしやすく、すべてにおいて非常に優れた言語になると私は信じている。」(「1章 良いパーツ」より)―本書は、JavaScript言語の「良いパーツ」に注目し、良質なコードを書くためのポイントを示唆する。「良いパーツ」を通してJavaScriptを再評価することで、見落とされていたJavaScript言語の本質が見えてくる。

ちなみに、JSのメソッドをオンラインで見るなら以下サイトがおすすめです。

http://devdocs.io/javascript/

Array

array.concat( item ... )

引数として渡された要素と自分自身を連結して、新しい配列を返します。

var a = ['a', 'b', 'c'];
var b = ['x', 'y', 'z'];
var c = ['1', '2', '3'];
console.log(a.concat(b, true));
// [ 'a', 'b', 'c', 'x', 'y', 'z', true ]

なお、複数の配列を連結することもできます。ここが非常に便利です。

var a = ['a', 'b', 'c'];
var b = ['x', 'y', 'z'];
var c = ['1', '2', '3'];

console.log(a.concat(a, a, b, b, c, c, true));

arrray.join( seperator )

配列の要素を結合して文字列を返します。

var a = ['a', 'b', 'c'];
console.log(a.join());
// a,b,c

「abc」という文字列が返ってくるかとおもいきや、
a,b,cという文字列が返ってきてしまいました。
これは、join()メソッドのセパレータのデフォルトが,だからです。

「abc」という文字列を得たい場合は、引数に空文字を渡してあげます。

var a = ['a', 'b', 'c'];
console.log(a.join(''));
// abc

もちろん、ことなるセパレータを渡すこともできます。

var today = ['2015', '11', '3'];
console.log(today.join('/'));
// 2015/11/3

array.pop()

配列の最後の要素を削除します。
pop()メソッドを実行した後の配列を変更する点に注意してください。

var a = ['a', 'b', 'c'];
console.log(a.pop());
console.log(a);
// 'c'
// a = ['a', 'b']

array.push( item... )

array.pop()とは逆に、配列の最後に要素を追加します。
返り値が、新しい要素のlengthプロパティであることに注目してください。

var a = ['a', 'b', 'c'];
console.log(a.push('d')); // 4
console.log(a);
// ['a', 'b', 'c', 'd']

引数には複数の要素を入れることもできます。

var a = ['a', 'b', 'c'];
console.log(a.push('x', 'y', 'z'));
console.log(a); // [ 'a', 'b', 'c', 'x', 'y', 'z' ]

array.concat()のように配列を連結したいときはどうすればいいでしょう。
以下のコードでは思い通りの返り値が返ってはきません。
配列の中に配列が格納された、二次元配列になってしまいます。

var a = ['a', 'b', 'c'];
var b = ['x', 'y', 'z'];

console.log(a.push(b)); // [ 'a', 'b', 'c', [ 'x', 'y', 'z' ] ]

この場合は、後述するapply()メソッドを使うことで実現できます。

var a = ['a', 'b', 'c'];
var b = ['x', 'y', 'z'];

Array.prototype.push.apply(a, b);
console.log(a); // [ 'a', 'b', 'c', 'x', 'y', 'z' ]

array.reverse()

配列を、その要素を逆の順番にして返します。
なお、もともとの配列も置き換えるので、以下のコードを実行してみると、
ab[ 'c', 'b', 'a' ]を返すことがわかります。
reverse()を実行した配列自体も変更する点に注意してください。

var a = ['a', 'b', 'c'];
var b = a.reverse();
console.log(a);
console.log(b);

array.shift()

配列から先頭の要素を削除して返します。
なお、削除後配列の各要素のインデックスの再配置を行うため、
パフォーマンスは配列の長さが長くなればなるほど、array.pop()より大幅に遅くなります。

var a = ['a', 'b', 'c'];
var b = a.shift();
console.log(a);
console.log(b);

array.slice( start, end )

配列からほしい箇所だけ切り取ります。
第二引数は省略可能です。

var a = ['a', 'b', 'c'];
var b = a.slice(0, 1);
var c = a.slice(1);
var d = a.slice(1, 2);
console.log(a);
console.log(b);
console.log(c);
console.log(d);

array.sort( compareFunction )

配列の中身をソートします。
以下のコードでは、配列の中身をアルファベット順に並び替えます。

var a = ['c', 'b', 'b', 'test', 'a'];
console.log(a.sort()); // [ 'a', 'b', 'b', 'c', 'test' ]

しかしこのsort()メソッド、そのままでは数値を並び替えることはできないのです。
以下の実行結果をみてみてください。「[ 1, 1, 10, 2, 20 ]」となっていますね。

var a = [1, 10, 2, 1, 20];
console.log(a.sort()); // [ 1, 1, 10, 2, 20 ]

実はJavaScriptのarray.sort()メソッドは、コールバック関数が渡されないと
数値をUnicodeの文字列に変換したうえで並び替えを実行してしまうのです。

If compareFunction is not supplied, elements are sorted by converting them to strings and comparing strings in Unicode code point order.
http://devdocs.io/javascript/global_objects/array/sort

したがって、数値を並び替えたいときは以下のようにします。

function compareNum(a, b) {
    return a - b;
}

var a = [1, 10, 2, 1, 20];
a.sort(compareNum);
console.log(a);

array.splice( start, deleteCount, item... )

「splice」の意味は「結合」です。
splice()メソッドでは、配列から要素を取り除き、新しい要素と入れ替えます。
実際に実行例を見てみましょう。

var a = ['a', 'b', 'c'];
var b = a.splice(1, 1, 'spliced');
console.log(a); // [ 'a', 'spliced', 'c' ]
console.log(b); // [ 'b' ]

splice()を実行した配列自体と、splice()メソッドの返り値の中身の違いに着目してください。
返り値は「削除された要素」であって、「spliceの実行結果」ではありません。

array.unshift( item... )

配列の先頭に要素を追加します。

var a = ['a', 'b', 'c'];
a.unshift('unshifted')
console.log(a); // [ 'unshifted', 'a', 'b', 'c' ]

Function

function.apply( thisArg, argArray )

関数を実行します。

実はJavaScriptには関数の呼び出し方が複数あって、『JavaScript: The Good Parts』では
以下の四通りで紹介されています。

  • メソッド呼び出しパターン
  • 関数呼び出しパターン
  • コンストラクタ呼び出しパターン
  • apply呼び出しパターン

たぶん一般によく使われるメソッド呼び出しや関数呼び出してはなく
わざわざapply()を使うときはどんな時でしょうか。
apply()をつかうと、パラメータとしてthisにセットされるオブジェクトをコントロールすることができます。

なお、複数の配列を引数に取るfunction.call()も参考にしてください。
以下の記事が非常に参考になります。

http://taiju.hatenablog.com/entry/20100515/1273903873

(なぜ本書で紹介されているのがcall()ではなくapply()なのかは、
想像ですが本書が書かれた時期によるものだと思います。)

Function.prototype.construct = function (aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};


Object

object.hasOwnProperty( name )

すべてのオブジェクトはObjectからhasOwnPropertyメソッドを継承します。
このメソッドは、ECMAScript2015以前のJSではよく使います。
プロトタイプチェーン上のプロパティの有無をチェックできるので、
オブジェクトの要素をfor in文でiterateする際にいちばん見たことがあるのではないでしょか。

具体的に言うと、toStringconstructorなどを継承してしまっているので、
そうしたプロパティを省きます。

var buz = {
    fog: 'stack'
};

for (var name in buz) {
  if (buz.hasOwnProperty(name)) {
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);
  } else {
    console.log(name); // toString or something else
  }
}

String

string.charAt( pos )

文字列内の指定された位置にある文字を返します。
JavaScriptはJavaのchar型のような、単一の変数を格納する文字型を持ちません。
そのため、単一の文字を返しますが、文字列扱いであることに注意してください。

var a = 'JavaScript';
console.log(a.charAt(8)); // p
console.log(a.charAt(100)); // 位置に文字がない場合は空文字列を返す

string.charCodeAt( pos )

基本的にはcharAtと同じですが、返り値が文字コードである点が異なります。
これも、この標準メソッドの存在を知っていないと、
「一度charAtで取得して、それを文字コードに変換して。。。」と二度手間を踏んでしまいます。

var a = 'JavaScript';
console.log(a.charCodeAt(8)); // pの文字コード「112」


string.indexOf( searchString, position )

文字列の中から、指定された文字列を検索しその場所を返します。
「最初の文字の場所」を返すことに注目してください。

var a = 'JavaScript';
console.log(a.indexOf('a')); // 1

string.lastIndexOf( searchString, position )

indexOfと同じですが、文字列の先頭からではなく末尾から検索をします。
したがって、「最後の文字の場所」を返します。

var a = 'JavaScript';
console.log(a.lastIndexOf('a')); // 3

string.match( regexp )

文字列に対して正規表現でパターンマッチングを行います。
非常に便利で、Webフロント開発でもNodeでサーバサイド書いている時でも使いドコロ満載です。

引数の正規表現パターンのgフラグの有無によって挙動が異なる点を確認してください。
gフラグがある場合、マッチするすべての結果を配列で返します。

var str = 'For more information, see Chapter 3.4.5.1';
var re = /(chapter \d+(\.\d)*)/i;
var found = str.match(re);

console.log(found);


(Sample)

string.replace( searchValue, replaceValue )

文字列の検索と置換を行います。
以下のコードを実行してみてください。

var a = 'JavaScript'.replace('a', 'A');
console.log(a); // 'JAvaScript'

最初の「a」のみ置換されたことがわかります。
というのも、第一引数のsearchValueが正規表現で、かつgフラグがセットされた場合のみ
すべての該当する箇所が置換されるのです。

var a = 'JavaScript'.replace(/a/g, 'A');
console.log(a); // 'JAvAScript'

string.search( regexp )

indexOfと似ていますが、引数に正規表現パターンを受け取ります。
マッチした場合、マッチしなかった場合の返り値の違いに着目してください。
マッチした場合でも、最初にマッチした文字の位置のみ返します。
つまり、gフラグは無視 されるということです。

var a = 'JavaScript';
console.log(a.search(/a/g)); // 最初にマッチした「1」を返す
console.log(a.search(/ttt/g)); // マッチしない場合は「-1」を返す

string.slice( start, end )

文字列の一部をコピーして新しい文字列を返します。
第二引数endを省略した場合は、最後までの文字を返します。
また、負の値の場合は末尾から取得します。

var a = 'JavaScript';
console.log( a.slice(3));
console.log( a.slice(3, 5));
console.log( a.slice(-3));

string.split( separator, limit )

splitメソッドは使いようによっては非常に強力なメソッドです。
文字列を複数の部分文字列に分割し、それらを含む配列を返します。
MarkdownをHTMLに変換する時、クロールしたファイルをパースする時などなど。。。

var a = 'JavaScript';
console.log(a.split(''));
console.log(a.split('', 5));

var ip = '192.168.1.0';
console.log(ip.split('.'));

string.fromCharCode( char... )

与えられた一連の数値を文字コードに変換して、文字列を生成します。

var a = String.fromCharCode(67, 97, 116);
console.log(a); // 'Cat'