ライブラリを作る

他のプログラミング言語同様、node.js でも自作の部品をライブラリとして再利用可能にする方法が提供されています。

node.js は ライブラリ化の方法として CommonJS で定義されるモジュールシステム [1] を採用して提供しています.node.jsの実装ではモジュールの保存先はファイルシステムであり,1つの.jsファイルが1つのモジュールとなります.

モジュールの定義例

CommonJS の例に従って math.js を定義します.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * math module
 */

// This function is exported.
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
        sum += args[i++];
    }
    return sum;
};

// This function is not exported.
function sum(){
   var s = 0, i = 0, args = arguments, l = args.length;
   while (i < l) {
      s += args[i++];
   }
   return s;
}

console.log('math module loaded');

exports.add は任意の引数を取り、その和を返す関数です.インタプリタを起動して,add が利用可能なことを確認します.

$ node
> var math = require('./math');
math module loaded
> math.add(1,2,3);
6
>

モジュールをロードするには ファイル名の .js を取り除いた部分を絶対パスあるいは相対パスで指定します.require 関数は requires.paths からモジュールを探しに行きます. require されたモジュールを確認してみると,

> math
{ add: [Function] }

のように表示されるはずです.モジュールは暗黙に exports オブジェクトを持っており,このオブジェクトが require の返却値となります.従って,exports に設定されていない sum 関数はモジュールの外部からは見えません.

モジュールはプロセス内で1度読み込まれると,以後は require しても再読込されません.

> var math = require('./math');
math module loaded
> math = require('./math');
> // math module loaded が表示されない

オブジェクト指向あれこれ

クラスの定義

クライアントサイドのJavaScriptでは prototype.js や jQuery など,それぞれのフレームワークの流儀によってクラスの継承方法を提供していました.これは JavaScript/ECMAの言語仕様自体に”継承”機能を提供する方法が定められていないからでしょうか.あるいは,クラス指向ではなくプロトタイプ指向であることが,継承を明示的に定義する必要性をなくしているのかもしれません.

詳細は省略しますが,クライアントサイドのJavaScript と同じく [2] クラスの定義(オブジェクトのコンストラクタ定義)は関数定義と同等です。

function ClassA(name){
   this._name = name
}

オブジェクトで利用できるメソッドは prototype メンバに定義します.

ClassA.prototype.hello = function(){
   console.log("Hello " + this._name);
}

ClassA というコンストラクタで定義されるオブジェクトを作るには new 演算子を使います.

var a = new ClassA('yssk22');
a.hello();

いわゆるクラスの継承は、prototype メンバのコピーになりますが,node.js では util.inherits という関数を使用します.

var util = require('util');
function ClassB(){
}
util.inherits(ClassB, ClassA);
[1]http://wiki.commonjs.org/wiki/Modules
[2]厳密には Google V8 の実装に依存します. V8のサイト には ECMA-262 3rd Editionの実装であることが明記されていますが,5th edition の仕様も一部実装しているようです.

Table Of Contents

Previous topic

二つのプログラミングモデル

Next topic

標準ライブラリ

This Page