LoginSignup
158
159

More than 5 years have passed since last update.

「JavaScriptパターン」ピックアップ

Last updated at Posted at 2014-01-09

はじめに

久々にjavascriptを弄ることになり、おさらいで各種書籍を読み直しています。
この際自分の中での暗黙知を明文化しておきたいと思い、しっくり来ているところだけピックアップしてみました。
(ほぼ自己メモです。)

for-inループ

  • プロトタイプ連鎖からきたプロパティを除外するためhasOwnPropertyを使う
pattern00.js

// for-inループ

var man = {
    hands: 2,
    legs: 2,
    heads: 1
};

for (var i in man) {
    if (man.hasOwnProperty(i)) {    // フィルタ
        console.log(i, ":", man[i]);
    }
}

forループ

  • myarray.lengthに対してのキャッシュ(ループ毎に問い合わせるよりも相当速い)
  • 単独varパターン(var宣言は1つに、そして関数先頭で)
  • for末尾のカウンタインクリメントにi++は使わず、i += 1にする。(++,--の「過剰なトリック」を避けるため)
pattern01.js
function looper() {
    var i = 0,
          max,
          myarray = [];
    // ...

    for (i=0, max = myarray.length; i < max; i += 1){
        // myarray[i]に対する処理
    }
}

switch

  • switchとcaseを揃える(波括弧のインデントルールの例外)
  • case内のコードはインデントする
  • caseの最後はbreak; で終わらせる
  • 意図的にbreakを省略して次のcaseに続けるのは避ける
  • switchの最後はdefault: で終わらせる
pattern02.js

var inspect_me = 0,
    result = '';

switch (inspect_me) {
case 0:
    result = "zero";
    break;
case 1:
    result = "one;"
    break;
default:
    result = "unknown";
}

インデント

  • 空白4個に揃える(JSLintのデフォルトなので)
  • インデントが空白かタブか、インデント幅は?等の話題は宗教戦争。正解は無い。(が必ず統一すること)
  • ifやforの中に文が1つしかなくても、波括弧は省略しない(文1カッコ無しだと、後々うっかり追加でインデント狂う副作用があるため)
pattern03.js
function outer(a, b) {
    var c = 1, 
        d = 2, 
        inner;

    if (a > b) {
        inner = function() {
            return {
                r : c - d
            };
        };
    } else {
        inner = function() {
            return {
                r : c + d
            };
        };
    }
}

命名規則

  • コンストラクタの頭文字は大文字
    var adam = new Person();
    function MyConstructor() {...}

  • 関数名はキャメルケース
    myFunction() 

  • 変数名は小文字アンダースコア区切り(関数名と見分ける事ができるため)
    var favorite_bands = "hoge"; 

  • 定数は大文字、単語区切りはアンダースコア
    var MAX_WIDTH = 800;

コメント

  • 習慣にするのが難しいけれど最も重要なのは、コメントを最新に保つこと (古くなったコメントは誤解を生み、コメントが無い方がよっぽどましな場合もある)
  • 以下はJSDocの例
pattern04.js
// JSDoc記法

    /**
     * 文字列を反転させる
     *
     * @param  {String} 反転させたい文字列
     * @return {String} 反転された文字列
     */
    var reverse = function(input) {
        // ...
        return output;
    }
  • YUIDocのデモはこちら 以下にも転記
pattern05.js
    /**
     * My JavaScript application
     *
     * @module myapp
     */
    var MYAPP = {};
    /**
     * A math utility
     * @namespace MYAPP
     * @class math_stuff
     */
    MYAPP.math_stuff = {

        /**
         * Sums two numbers
         *
         * @method sum
         * @param  {Number} a First number
         * @param  {Number} b The second number
         * @return {Number} The sum of the two inputs
         */
        sum : function(a, b) {
            return a + b;
        },

        /**
         * Multiplies two numbers
         *
         * @method multi
         * @param  {Number} a First number
         * @param  {Number} b The second number
         * @return {Number} The two inputs multiplied
         */
        multi : function(a, b) {
            return a * b;
        }
    };

    /**
     * Constructs Person objects
     * @class Person
     * @constructor
     * @namespace MYAPP
     * @param {String} first First name
     * @param {String} last Last name
     */
    MYAPP.Person = function(first, last) {
        /**
         * Name of the person
         * @property first_name
         * @type String
         */
        this.first_name = first;
        /**
         * Last (family) name of the person
         * @property last_name
         * @type String
         */
        this.last_name = last;

    };

    /**
     * Returns the name of the person object
     *
     * @method getName
     * @return {String} The name of the person
     */
    MYAPP.Person.prototype.getName = function() {
        return this.first_name + ' ' + this.last_name;
    }; 

コンストラクタ

  • コンストラクタは単なる関数ですが、newを使って呼び出すことができる。
  • newを付け忘れて呼ぶと構文エラーにも実行時エラーにもならないが、thisがグローバルオブジェクトを指してしまう。

コンストラクタ関数をnewを使って呼び出す時、関数内部では以下のようになります

  • 空のオブジェクトが作成され、変数thisで参照される。thisはこの関数のプロトタイプを継承する。
  • thisが参照するオブジェクトにプロパティとメソッドが追加される。
  • thisが参照する新しく作られたオブジェクトは、関数の最後で暗黙に返される。
pattern06.js
var Person = function(name) {
    this.name = name;
    this.say = function() {
        return "I am " + this.name;
    };
};

上記例ではthisにメソッド say()を追加しているが、メモリが無駄なのでプロトタイプに追加すべき

pattern07.js
Person.prototype.say = function () {
    return "I am " + this.name;
};
158
159
2

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
158
159