モジュール設計

CommonJS規範

node.js 主にServer側 synchronous

var math = require('math');

math.add(2,3);

AMD規範

require.js 主にBrowser側 asynchronous

require(['math'], function(math){

math.add(2, 3);

});

基本モジュール

var jsModule = function(){

var privateVar = "A";

var privateMethod = function(){

return privateVar;

};

return {

printVar: function(){

return privateMethod();

}

};

}();

console.log(jsModule.printVar()); //A

子モジュール

jsModule.subModule = function(){

var anotherPrivateVar = "B";

var sayWord = function(str){

switch(str)

{

case "A":

return "A B";

default:

return "C";

}

};

return {

say: function(){

return sayWord(jsModule.printVar());

}

}

}();

console.log(jsModule.subModule.say()); //A B

メソッドを追加

var jsModule = function(){

var privateVar = "A";

var privateMethod = function(){

return privateVar;

};

var obj = {

printVar: function(){

return privateMethod();

}

};

obj.appendVar = function(){ //追加

return "B";

}

return obj;

}();

console.log(jsModule.printVar()); //A

console.log(jsModule.appendVar()); //B

拡張モジュール

var newJsModule = function(super_module){

var parent_module = super_module;

parent_module.printVar = function(){ //Override

return "B";

};

var privateMethod2 = function(){

return "D";

};

return {

newPrintVar: function(){

return parent_module.printVar();

}

}

}(jsModule);

console.log(newJsModule.newPrintVar()); //B

関数型プログラミング

★高階関数

・引数として関数を受け取る

書き方1

(function(f, a) {

return f(a) + f(a);

})(function(n) {

return n * n;

}, 10); // 200

書き方2

var g = function(f, a) { return f(a) + f(a); };

var h = function(n) { return n * n; };

g(h, 10); // 200

・戻り値として関数を返す

書き方1

var g = function(n) {

return function() {

return n * n;

};

};

呼び方1

var h = g(10);

h(); // 100

呼び方2

g(10)(); // 100

書き方2

(function(n) {

return function() {

return n * n;

};

})(10)(); // 100

★モジュール構造

(function(MyModule, $, undefined) {

MyModule.help = {

...

};

MyModule.help.cache = {

...

};

...

}(window.MyModule || {}, jQuery));

オブジェクト向けの設計

1.コンストラクタ+プロトタイプ方式

特徴:thisとprototypeを使う

・クラスの書き方

・書き方1

function Parent(sColor) {

this.color = sColor;

}

prototypeを再定義

Parent.prototype = {

showColor: function(){

alert(this.color);

}

};

prototypeにプロパティを追加

Parent.prototype.showColor = function() {

alert(this.color);

}

・書き方2

function Parent(sColor) {

this.color = sColor;

if (typeof showColor != "function" ){ // if(this.showColor === undefined)

Parent.prototype.showColor = function() {

alert(this.color);

};

}

}

//利用側

var class1 = new Parent("red");

class1.showColor();

class1.showColor = function () { //処理変更

// do something

}

・書き方3

var Parent = function(){

this.color = "green";

this.prototype.showColor = function() {

alert(this.color);

};

};

・継承の書き方

・書き方1

function Child(sColor, sName) {

Parent.apply(this, arguments);

this.name = sName;

}

・書き方2

Child.prototype = new Parent(); ←メモリ消費

Child.prototype.constructor = Child;

Child.prototype.showName = function() {

alert(this.name);

}

//利用側

・呼び方1

var class1 = new Child("red", "Andy");

class1.showName();

・呼び方2

var class2 = {};

Child.call(class2, "red", "Andy"); //書き方1

Child.apply(class2, ["red", "Andy"]); //書き方2

class2.showName();

・書き方3(推薦)

function extend(Sub, Super) {

var F = function(){};

F.prototype = Super.prototype;

Sub.prototype = new F();

Sub.prototype.constructor = Sub;

Sub.uber = Super.prototype;

}

//利用側

extend(Child, Parent);

var class1 = new Child("red", "Andy");

class1.showName();

※callとapplyの違いは2番目からの引数

2.Minimalist方式

特徴:thisとprototypeを使わない

・クラスの書き方

・書き方1

var Parent = {

createNew: function(){

var parent = {};

parent.color = "xxx";

parent.showColor = function(){...};

return parent;

}

};

・書き方2

var Parent = {

createNew: function(){

var parent = {

color : "xxx",

showColor : function() {

...

}

};

return parent;

}

};

//利用側

var class1 = Parent.createNew();

class1.showColor();

・継承の書き方

var Child = {

createNew: function(){

var val = "xxx"; //private変数

var method = function() { ... }; //privateメソッド

var child = Parent.createNew();

child.name = "yyy"; //publicプロパティ

child.action = function(){...}; //publicメソッド

return child;

}

};

・getter/setterの書き方

var Sample = {

name : "xxx",

createNew: function(){

var sample = {};

sample.getName = function(){ return Sample.name; };

sample.setName = function(x){ Sample.name = x; };

return sample;

}

};

//利用側

var sample1 = Sample.createNew ();

var sample2 = Sample.createNew ();

sample1.getName(); //出力:xxx

sample2.setName("yyy");

sample1.getName(); //出力:yyy