• 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細

このWikiはいつでも誰でも編集できます

JavaScript コーディング規約

提供: WordPress Codex 日本語版
移動先: 案内検索

注意: この記事は「Core Contributor Handbook」の「JavaScript Coding Standards」(2016年8月12日時点)の訳です。
最新版については英語版を参照してください。

今や JavaScript は WordPress コアだけでなく、テーマやプラグインなどの WordPress 周辺のアプリケーションにおいても重要なコンポーネントになっています。既存のコア PHP、HTML、CSS の WordPress 規約と同じレベルでコードの一貫性を保つには、JavaScript コードのフォーマットやスタイルにも規約が必要なことは明らかです。

多数のコントリビューターが参加していても、すべてのコードは、一人の人間がコーディングしたかのように見えなければならない。
- Principles of Writing Consistent, Idiomatic JavaScript

WordPress JavaScript コーディング規約は「jQuery JavaScript Style Guide」を基にしていますが、次の点で異なります。

  • WordPress は文字列の宣言にシングルクォートを使用します。
  • case 文は switch ブロック内でインデントします。
  • 関数全体がクロージャでラップされている場合も含め、関数の本体は常にインデントします。
  • WordPress PHP コーディング規約と一貫性を保つため、スペースのルールが一部異なります。
  • jQuery の 100文字制限を推奨しますが、厳密には強制しません。

この記事の例は直接「jQuery JavaScript Style Guide」から引用していますが、上で挙げた相違点はすべて反映されています。この記事の規約と例は、特にアンチパターンと明記されているもの以外すべて WordPress JavaScript コーディングにおけるベストプラクティスになっています。

参照: WordPress コーディング規約WordPress インラインドキュメント規約

コードのリファクタリング

"リファクタリングのためだけにコードを変更しないでください。"
- リード開発者 Andrew Nacin

WordPress の多くの JavaScript コードには統一したスタイルがありません。WordPress では徐々にこれらを改善し、コードをクリーンで読みやすいものにするよう努めています。

コーディング規約は確かに重要ですが、規約に合わせるためだけに古い .js ファイルをリファクタリングするほど暇ではありません。古いファイルの「スペースを調整する」だけのパッチなどは絶対にやめてください。

なお新規に作成、更新された JavaScript コードは、コーディング規約に順守し、JSHint にパスしたことをレビューします。

スペース

スペースはコードの中で自由に使えます。「悩んだら、スペースを入れてください」

十分にスペースが入ることで、開発者はコードが読みやすくなります。仮にファイルサイズが増加しても、後続の縮小プロセスにより不要なスペースは削除され、ブラウザでのロード、処理に最適化したファイルが作成されます。

  • 「本物のタブ」でインデントしてください。
  • 行末や空行にスペースを入れないでください。
  • 1タブを4スペースと数え、1行あたり80文字以下を目標としてください。100文字は越えないでください。これは「強制ではありません」が、一般に長い行は読みにくく、整理されていないコードです。
  • ifelseforwhiletry ブロックは常にブレース「{}」を使用し、常に複数行にしてください。
  • 単項特殊文字演算子 (例: 「++」「--」) はオペランドの次にスペースを入れないでください。
  • すべての 「,」および「;」の前にスペースを入れないでください。
  • 文の終わりに使用されるすべての「;」は行末に書いてください。
  • オブジェクト定義内のプロパティ名と、続く「:」の間にスペースを入れないでください。
  • 三項条件の「?」と「:」は両側にスペースを入れてください。
  • 空のコンストラクタにスペースを入れないでください。例:「{}」「[]」「fn()」。
  • 各ファイルの最後には空行を追加してください。
  • すべての否定演算子「!」にはスペースを続けください。(*)
  • すべての関数の本体は1つのタブでインデントしてください。関数全体がクロージャでラップされても同様です。(*)
  • ドキュメントブロックや行の中でスペースを使用して単語や文の位置を揃えても構いません。ただし行の始まりはタブでインデントしてください。(*)

(*): スペースの扱いに関しては WordPress の JavaScript 規約は「jQuery JavaScript Style Guide」よりも若干広めです。この違いは WordPress コードにおける PHP ファイルと JavaScript ファイルとの一貫性の維持から生じています。

スペースは行末に簡単に紛れ込むため注意してください。JSHint では行末のスペースはエラーです。コーディング中にスペースを見つける方法としては、テキストエディタでスペース文字を表示する方法があります。

オブジェクト

オブジェクト定義は、短い場合には1行で書いても構いません。ただし最大長の制限は忘れないでください。オブジェクト定義が長く1行に収まらない場合は、1行ごとに1つプロパティを定義する形で分割してください。プロパティ名は予約語、または特殊文字を含む場合のみクォートしてください。

// 良い
var map = {
    ready: 9,
    when: 4,
    'you are': 15
};
 
// 小さなオブジェクトの場合は許される
var map = { ready: 9, when: 4, 'you are': 15 };
 
// 悪い
var map = { ready: 9,
    when: 4, 'you are': 15 };

配列と関数呼び出し

要素と引数の前後には常にスペースを入れてください。

array = [ a, b ];
 
foo( arg );
 
foo( 'string', object );
 
foo( options, object[ property ] );
 
foo( node, 'property', 2 );

例外:

// PHP 規約との一貫性のため、配列表記のキー値に使用される
// 文字列定数や整数の前後にスペースを入れないでください。
prop = object['default'];
firstArrayElement = arr[0];
 
// 関数で、単一引数がコールバック、オブジェクト、配列の場合:
// 引数の両側にスペースを入れない
foo(function() {
    // 何か実行する
});
 
foo({
    a: 'alpha',
    b: 'beta'
});
 
foo([
    'alpha',
    'beta'
]);
 
// 関数で、最初の引数がコールバック、オブジェクト、配列の場合:
// 最初の引数の前にスペースを入れない
foo(function() {
    // 何か実行する
}, options );
 
// 関数で、最後の引数がコールバック、オブジェクト、配列の場合:
// 最後の引数の後にスペースを入れない
foo( data, function() {
    // 何か実行する
});

良いスペースの例

var i;
 
if ( condition ) {
    doSomething( 'with a string' );
} else if ( otherCondition ) {
    otherThing({
        key: value,
        otherKey: otherValue
    });
} else {
    somethingElse( true );
}
 
// jQuery とは異なり、WordPress では否定演算子 ! の後にスペースを入れます。
// これは PHP 規約との一貫性のためです。
while ( ! condition ) {
    iterating++;
}
 
for ( i = 0; i < 100; i++ ) {
    object[ array[ i ] ] = someFn( i );
    $( '.container' ).val( array[ i ] );
}
 
try {
    // 式
} catch ( e ) {
    // 式
}


セミコロン

セミコロンを使用してください。自動セミコロン挿入 (ASI) に頼らないでください。


インデントと改行

複雑な文もインデントと改行により読みやすくなります。

インデントにはタブを使用してください。即時実行関数のように、関数全体がクロージャに含まれる場合も関数の内部は1つのタブでインデントしてください。

(function( $ ) {
    // インデント
 
    function doSomething() {
        // インデント
    }
})( jQuery );

ブロックとブレース

ifelseforwhiletry ブロックは常にブレース「{}」を使用し、常に複数行にしてください。開始ブレースは関数定義、条件、ループと同じ行に書いてください。終了ブレースはブロックの最後の行の次の行に書いてください。

var a, b, c;
 
if ( myFunction() ) {
    // 式
} else if ( ( a && b ) || c ) {
    // 式
} else {
    // 式
}

複数行

文が長く、1行に収まらない場合は演算子の直後で改行してください。

// 悪い
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c
    + ' is ' + ( a + b + c );
 
// 良い
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c +
    ' is ' + ( a + b + c );

読みやすさのため、行を論理的なグループで分割してください。たとえば三項演算子では1行に1つ式を書く形で、それぞれの式に分割してください。

// 許される
var baz = ( true === conditionalStatement() ) ? 'thing 1' : 'thing 2';
 
// もっと良い
var baz = firstCondition( foo ) && secondCondition( bar ) ?
    qux( foo, bar ) :
    foo;

条件が長く行を折り返す場合、後続の行は1レベル分、追加でインデントし、本体と区別してください。

if ( firstCondition() && secondCondition() &&
        thirdCondition() ) {
    doStuff();
}

連続したメソッド呼び出し

連続したメソッド呼び出しが長く、行を折り返す場合、1行に1呼び出しを書いてください。最初の呼び出しも、メソッドが呼び出されるオブジェクトの次の行に書いてください。メソッドがコンテキストを変える場合は、追加のインデントを使用してください。

elements
    .addClass( 'foo' )
    .children()
        .html( 'hello' )
    .end()
    .appendTo( 'body' );

代入とグローバル

var での変数宣言

関数の定義は、コンマで区切った var 文によるローカル変数の宣言で始めてください。var を使用せずに変数を宣言した場合、変数が外部スコープ、最悪の場合はしばしばグローバルスコープに落ち込み、データが意識しないうちに参照されたり、変更されます。

var 文内では、定義は1つの行にまとめる一方で、代入は新しい個別の行に書いてください。後続の行は追加のタブでインデントしてください。多くの行が必要なオブジェクトや関数はインデントが非常に深くなるため、var の外で代入してください。

// 良い
var k, m, length,
    // 後続の行は1タブ分、インデントする
    value = 'WordPress';
 
// 悪い
var foo = true;
var bar = false;
var a;
var b;
var c;

グローバル

以前は WordPress コアはグローバル変数を多用していました。今もコアの JavaScript ファイルはプラグイン内部で使用されているものがあるため、既存のグローバル変数を除去することはできません。

ファイル内で使用されるすべてのグローバル変数はファイルの先頭でドキュメントしてください。複数のグローバル変数はコンマで区切って並べることもできます。

次の例で passwordStrength はファイル内で許可されるグローバル変数です。

/* global passwordStrength:true */

passwordStrength の次の「true」はこのグローバル変数がこのファイル内で定義されることを意味します。他のどこかで定義されたグローバル変数にアクセスする場合には :true を削除し、グローバル変数が読み出し専用であることを明示してください。

共通ライブラリー

Backbone、jQuery、Underscore、グローバルの wp オブジェクトは、ルートの .jshintrc ファイル内で、許可されたグローバル変数としてすべて登録されています。

Backbone と Underscore はいつでも直接アクセスできます。jQuery は jQuery オブジェクトを無名関数に渡すことで $ を介してアクセスできます。

(function( $ ) {
  // 式
})( jQuery );

これで .noConflict() 呼び出しや他の変数を使用した $ の設定は不要になります。 追加したり、変更するファイルでは、以前に設定されたプロパティを上書きしないよう、wp オブジェクトが安全にグローバル変数にアクセスします。

// ファイルの先頭で、wp に既存の値を設定する (もしあれば)
window.wp = window.wp || {};

命名規則

変数名と関数名は省略しない完全な単語を使用し、最初の文字を小文字にした camelCase を使用してください。ここは「WordPress PHP コーディング規約」と異なる部分です。

new での利用を想定するコンストラクターは最初の文字を大文字にしてください。例: UpperCamelCase

名前は、過剰にならない範囲で説明的なものににしてください。例外はイテレーターです。例えばループ内のインデックスに i を使用できます。

コメント

コメントは参照するコードの前に書いてください。コメントの前は常に1行空けてください。コメントの最初の文字は大文字とし、コメントが文の場合は最後にピリオドを付けてください。コメントトークン「//」とコメントの間にはスペース1個分空けてください。

単一行のコメント

someStatement();
 
// Explanation of something complex on the next line
$( 'p' ).doSomething();

長いコメントの場合は複数行を使用してください。

/**
 * This is a comment that is long enough to warrant being stretched
 * over the span of multiple lines.
 */

内部コメントは仮引数リスト内の特殊な引数へのアノテーションで使用される場合のみ、例外的に許可されます。

function foo( types, selector, data, fn, /* INTERNAL */ one ) {
    // 何か実行する
}

等価性

抽象的な等価性比較 (==) よりも厳格な等価性比較 (===) を使用してください。例外は undefinednull の両方を null の方法で比較する場合のみです。

// ある重要な理由により、undefined と null 値の両方を比較する
if ( undefOrNull == null ) {
    // 式
}

型のチェック

オブジェクトの型をチェックする場合に推奨される方法は以下のとおりです。

  • 文字列: typeof object === 'string'
  • 数: typeof object === 'number'
  • ブール値: typeof object === 'boolean'
  • オブジェクト: typeof object === 'object' または _.isObject( object )
  • プレーンオブジェクト: jQuery.isPlainObject( object )
  • 関数: _.isFunction( object) または jQuery.isFunction( object )
  • 配列: _.isArray( object ) または jQuery.isArray( object )
  • 要素: object.nodeType または _.isElement( object )
  • null: object === null
  • null または undefined: object == null
  • undefined (未定義):
    • グローバル変数: typeof variable === 'undefined'
    • ローカル変数: variable === undefined
    • プロパティ: object.prop === undefined
    • 上のすべて: _.isUndefined( object )

Backbone または Underscore がすでに使われている場合は常に、jQuery でなく、Underscore.js の型チェックメソッドを使用してください。

文字列

文字列定数にはシングルクォートを使用してください。

var myStr = 'strings should be contained in single quotes';

文字列にシングルクォートが含まれる場合は、バックスラッシュ (\) でエスケープしてください。

// 文字列内のシングルクォートはエスケープ
'Note the backslash before the \'single quotes\'';

switch 文

switch 文の使用は一般に推奨されません。ただし大量の case がある場合には有用なのも事実です。特に、複数の case が同じブロックで処理されたり、下に落ちていき default で拾うロジックが有効に機能する場合です。

switch 文を使用する場合

  • default 以外の各 case では break を使用してください。次の case に意図的に落とす場合は、明示的にドキュメントしてください。
  • switch 内の case 文は1個のタブでインデントしてください。
switch ( event.keyCode ) {
 
    // ENTER と SPACE の両方で x() を呼び出し
    case $.ui.keyCode.ENTER:
    case $.ui.keyCode.SPACE:
        x();
        break;
    case $.ui.keyCode.ESCAPE:
        y();
        break;
    default:
        z();
}

switch 文から値を返すことは推奨されません。case ブロックを使用して値を設定し、最後に値を return してください。

function getKeyCode( keyCode ) {
    var result;
 
    switch ( event.keyCode ) {
        case $.ui.keyCode.ENTER:
        case $.ui.keyCode.SPACE:
            result = 'commit';
            break;
        case $.ui.keyCode.ESCAPE:
            result = 'exit';
            break;
        default:
            result = 'default';
    }
 
    return result;
}

ベストプラクティス

配列

JavaScript で配列を作成する場合は、new Array() 記法ではなく、短い [] コンストラクターを使用してください。

var myArray = [];

構築中に配列を初期化できます。

var myArray = [ 1, 'WordPress', 2, 'Blog' ];

JavaScript では連想配列はオブジェクトとして定義されます。

オブジェクト

JavaScript には多くのオブジェクト作成方法があります。オブジェクトリテラル記法、{} は両方ともパフォーマンスがよく、可読性に優れます。

var myObj = {};

オブジェクトが特定のプロトタイプを必要としない限り、オブジェクトリテラル記法を使用してください。プロトタイプを必要とする場合は、new でコンストラクター関数を呼び出してオブジェクトを作成してください。

var myObj = new ConstructorMethod();

オブジェクトプロパティはドット記法でアクセスしてください。例外はキーが変数、予約語、正しい識別子でないかもしれない文字列の場合です。

prop = object.propertyName;
prop = object[ variableKey ];
prop = object['default'];
prop = object['key-with-hyphens'];

ヨーダ記法

PHP コーディング規約」との一貫性のため、オブジェクトを文字列、ブール値、整数、他の定数や文字列と比較する場合はヨーダ記法を使用してください。変数は右側に置き、定数や文字列は左側に置きます。

if ( true === myCondition ) {
    // 何か実行する
}

「最初、奇妙に見えるかもしれませんが、そのうち慣れるはずです。」

イテレーション

for ループを使用して大きなコレクションをイテレートする場合、毎回ループの最大値を再計算するのではなく、いったん変数に代入して使用してください。

// 良い & 効果的
var i, max;
 
// getItemCount() が1度だけ呼ばれる
for ( i = 0, max = getItemCount(); i < max; i++ ) {
    // 何か実行する
}
 
// 悪い & 潜在的に間違い
// getItemCount() が毎回呼ばれる
for ( i = 0; i < getItemCount(); i++ ) {
    // 何か実行する
}

Underscore.js コレクション関数

Underscore の コレクションと配列メソッド を学習し、理解してください。_.each_.map_.reduce 等を使用すると、大きなデータ集合の変換において効果的で、可読性にも優れます。

また Underscore では通常の JavaScript オブジェクトに対して jQuery スタイルのチェーンが可能です。

var obj = {
    first: 'thing 1',
    second: 'thing 2',
    third: 'lox'
};
 
var arr = _.chain( obj )
    .keys()
    .map(function( key ) {
        return key + ' comes ' + obj[ key ];
    })
    // チェーン終了
    .value();
 
// arr === [ 'first comes thing 1', 'second comes thing 2', 'third comes lox' ]

jQuery コレクションでのイテレート

jQuery オブジェクトのコレクションをイテレートする場合のみ、jQuery でイテレートしてください。

$tabs.each(function( index, element ) {
    var $element = $( element );
 
    // $element に対して何か実行する
});

生データや素の JavaScript オブジェクトのイテレートには決して jQuery を使わないでください。

JSHint

JSHint は JavaScript コード内のエラーを発見する自動化コード品質検証ツールです。WordPress の開発ではフロントエンド側にロジックや構文のエラーを持ち込まないよう JSHint を使用してパッチを迅速に検証しています。

JSHint のインストールと実行

JSHint は実行に Grunt と呼ばれるツールを使用します。JSHint も Grunt も Node.js で書かれたプログラムです。WordPress 開発コードに付属する構成ファイルを使用すると、これらのツールを簡単にインストールし、構成できます。

Node.js をインストールするには Node サイトのインストールのリンクをクリックしてください。オペレーティングシステムに合った正しいインストールファイルがダウンロードされます。プログラムのインストールにはオペレーティングシステムごとのインストール手順に従ってください。

Node.js のインストール後にコマンドラインウィンドウを開き、WordPress SVN リポジトリのコピーをチェックアウトしたディレクトリに「cd ~/directoryname」で移動してください。package.json ファイルのあるディレクトリにいるはずです。

次にコマンドラインウィンドウで「npm install」と入力します。WordPress 開発で使用するすべての Node パッケージをダウンロードし、インストールします。

最後に「npm install -g grunt-cli」を入力して、Grunt コマンドラインインターフェース (CLI) パッケージをインストールします。Grunt CLI を使用して WordPress の Grunt タスクを実際に実行します。

ここで「grunt jshint」と入力すると、すべての WordPress JavaScript ファイルの構文エラー、ロジックエラーを Grunt で検証できます。コアコードのみを検証するには「grunt jshint:core」、ユニットテスト .js ファイルのみを検証するには「grunt jshint:tests」と入力してください。

JSHint の設定

JSHint に使用される構成オプションは WordPress SVN リポジトリ内の .jshintrc ファイルに保存されます。このファイルでは JSHint が WordPress ソースコード内のどのエラーにフラグを立てるべきかを定義します。

単一ファイルの検証

JSHint の検証に単一ファイルを指定するには、コマンドの最後に「--file=filename.js」を追加してください。例えば、次の行は WordPress の JavaScript ファイル内のファイル「admin-bar.js」のみを検証します。

grunt jshint:core --file=admin-bar.js

次の行は ユニットテスト用ディレクトリ内のファイル「password-strength-meter.js」のみを検証します。

grunt jshint:tests --file=password-strength-meter.js

開発中に1つ、2つの特定のファイルだけ変更しており、JSHint 実行のたびに毎回すべてのファイルの検証を待ちたくない場合に、JSHint を単一ファイルに絞ると効率的です。

JSHint オーバーライド - ignore ブロック

ファイルの一部を JSHint の検証から除外したい場合があります。たとえばツールバーのスクリプトファイルが 縮小された jQuery HoverIntent プラグインのコードを含む場合、これは WordPress コア JavaScript の一部ですが、サードパーティ製のコードのため JSHint をパスする必要はありません。

JSHint の処理から特定のファイルの部分を除外するには、JSHint ディレクティブコメントで囲んでください。

/* jshint ignore:start */
if ( typeof jQuery.fn.hoverIntent === 'undefined' ) {
    // hoverIntent r6 - Copy of wp-includes/js/hoverIntent.min.js
    (function(a){a.fn.hoverIntent=...............
}
/* jshint ignore:end */

Credits

最新英語版: Core Contributor Handbook > JavaScript Coding Standards