カテゴリ:Computer( 114 )
jQueryを読めるようになりたい
相変わらず、jQueryを扱えるように勉強しています。
だいぶ扱えるようになってきて楽しい楽しいJavaScriptライフです。

ですが、そろそろ伸び悩みの頃に近づいてる気がします。
JavaScript-erとしてもjQuery-erとしても。

なのでjQueryが中でどんなトリックを使って(地道な処理なのかもしれないが)いるのか読んでみたいのです。
幸いにオープンソースなので、いまでも中は見れます。

ただ、今の僕には見えるだけで、(まるで)読めません。
一体どうやって読んでいくものなのでしょう?
とっかかりがほしいです。
[PR]
by redchant | 2011-11-02 22:54 | Computer
ウズラ本 第7章「デザインパターン」 イテレータ
本をほとんど丸写しですが。

var agg = (function() {

var index = 0,
data = [1, 2, 3, 4, 5],
length = data.length;

return {

next: function() {
var element;
if (!this.hasNext()) {
return null;
}
element = data[index];
index++;
return element;
},

hasNext: function() {
return index < length;
}

};

}());

while (agg.hasNext()) {
console.log(agg.next());
}


とても単純な実装。
このパターンを使うべき場合は、複雑なデータ体からデータをループで取得したい場合。
[PR]
by redchant | 2011-03-08 20:12 | Computer
ウズラ本 第7章「デザインパターン」 ファクトリ

// 親コンストラクタ
function Car() {};

Car.prototype.drive = function() {
console.log("I drive " + this.name);
};

// ファクトリ関数
Car.factory = function(type) {
var newcar;

if (typeof Car[type] !== "function") {
throw {
name: "Error",
message: type + " doesn't exist"
};
}

// 継承する
if (typeof Car[type].prototype.drive !== "function") {
Car[type].prototype = new Car();
}

// 新しいインスタンスを作成する
newcar = new Car[type];

return newcar;
}

// 以下、ファクトリで作成されるモノのコンストラクタ
Car.Compact = function() {
this.name = "Compact";
};
Car.Convertible = function() {
this.name = "Convertible";
};
Car.SUV = function() {
this.name = "SUV";
};

var compact = Car.factory("Compact");
compact.drive(); // I drive Compact

var convertible = Car.factory("Convertible");
convertible.drive(); // I drive Convertible

var suv = Car.factory("SUV");
suv.drive(); // I drive SUV


はて、何が便利になるのだろう。
本書には、

「ファクトリの利用者に、コンパイル時の型(クラス)を知らなくてもオブジェクトを作成できる手段を提供する」

とある。
コンストラクタを見えなくする、感じですかね。
[PR]
by redchant | 2011-03-07 21:54 | Computer
ウズラ本 第7章「デザインパターン」 シングルトン
◆自己定義関数版。

function Universe() {

// 唯一のインスタンス
var instance;

// 自己定義
Universe = function() {
return instance;
}

// プロトタイプを引き継ぐ
Universe.prototype = this;

// 唯一のインスタンスを作成する
instance = new Universe();

return instance;
}

var uni1 = new Universe();
var uni2 = new Universe();

console.log(uni1 === uni2); // true



◆即時関数版。
こちらの方が読みやすいな。

var Universe;

(function() {

// 唯一のインスタンス
var instance;

Universe = function() {
if (instance) {
return instance;
}
instance = this;
};
return instance;
}());

var uni1 = new Universe();
var uni2 = new Universe();

console.log(uni1 === uni2);


[PR]
by redchant | 2011-03-07 21:15 | Computer
ウズラ本 第6章「コード再利用パターン」


第6章「コード再利用パターン」。
「継承」について大半が書かれているが、大半がわからない;
なので、復習だ。

この本では、クラシカルな継承とモダンな継承、とに分けている。
クラシカルとは、「古典的」という意味ではなく、「クラスっぽい」を意味したいらしく紛らわしい。
モダンも別に「現代的」を意味するわけでなく、「クラシカル」に対する意味だそうです紛らわしい。
言ってみれば、JavaライクかJavaScriptかってことを意味したいようだ。


◆クラシカルなパターンその1:デフォルトパターン
親となるコンストラクタ関数でオブジェクトを作成し、
子となるコンストラクタ関数のprototypeに代入する方法で、最も一般的らしい。

function inherit(C, P) {
C.prototype = new P();
}


この方法は、まあ簡単なので、利点も欠点も本書に書いてあるとおりで、よくわかった。


◆クラシカルなパターンその2:コンストラクタ拝借

function Article() {
this.tags = ["js", "css"];
}

// コンストラクタ拝借パターンを使ってArticleを継承
function StaticPage() {
Article.call(this);
}

var page = new StaticPage();

console.log(page.hasOwnProperty("tags")); // true


なんと、trueとな!?
StaticPageの中でやってることがよくわかりません。
thisはStaticPage自身を指すんだっけ?

call(とapply)がやっぱりよくわからない、ということでサイ本を参照してみた。
callはすべての関数にあるメソッドであると。
あたかもあるオブジェクトのメソッドであるかのように関数を呼び出せると。
つまり、this.Article();、、、みたいな?
つまりつまるところ、StaticPageのプロパティにtagsが設定されたということ、、、か!?
callこそが「拝借」ということなんだろうか。便利だなあ。

ということで、
◆クラシカルなパターンその3:プロトタイプを拝借して設定する
その1とその2の組み合わせだす。

function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
return this.name;
}

function Child(name) {
Parent.call(this, name);
}
Child.prototype = new Parent();

var kid = new Child("redchant");
console.log(kid.say()); // redchant


わかる!わかるよ!

◆クラシカルなパターンその4:プロトタイプを共有する

function inherit(C, P) {
C.prototype = P.prototype;
}


うん、簡単だあ。
本書の図6-7を見ればもっとあきらかだ。

◆クラシカルなパターンその5:一時的コンストラクタ
その4の問題点は、親と子で同一のプロトタイプを共有すること。
問題なければ良いのだが、問題であれば、このパターンを。
直接のリンクを一時的なコンストラクタで解除する。

function inherit(C, P) {
var F = function() {}; // 一時的なコンストラクタ
F.prototype = P.prototype; // 一時的なコンストラクタに退避
C.prototype = new F();
}


これも図をみるとわかりやすいのだが…

◆Klass
ここ、誤植か間違いがないかい?

◆プロトタイプによる継承
クラシカルなパターンその5:一時的コンストラクタに似ているのお。

// 継承関数
function object(o) {
var F = function() {};
F.prototype = o;
return new F();
}

// 親コンストラクタ
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
};

var papa = new Person("Adam");

// 継承してみる
var kid = object(papa);

console.log(kid.getName());



◆プロパティのコピーによる継承
浅いコピーによる継承関数。

function extend(parent, child) {
var i;
for (i in parent) {
if (parent.hasOwnProperty(i)) {
child[i] = parent[i];
}
}
return child;
}


この関数合ってるのかなあ?
if文の条件 ↓ じゃないのかなあ?
!child.hasOwnProperty(i)

配列やオブジェクトは参照渡しなので、浅いコピーでは継承元と継承したオブジェクトが、
同じオブジェクトを参照してしまい、都合が悪い場合がある。

対して深いコピーによる継承関数。

function extendDeep(parent, child) {
var i,
toStr = Object.prototype.toString,
astr = "[object Array]";

for (i in parent) {
if (parent.hasOwnProperty(i)) {
if (typeof parent[i] === "object") {
child[i] = (toStr.call(parent[i]) === astr) ? [] : {};
extendDeep(parent[i], child[i]);
} else {
child[i] = parent[i];
}
}
}

return child;
}

var dad = {
counts: [1, 2, 3],
reads: {paper: true}
};

var kid = {};
extendDeep(dad, kid);
console.log(kid);
kid.counts.push(4);
console.log(kid.counts.toString()); // 1, 2, 3, 4
console.log(dad.counts.toString()); // 1, 2, 3

console.log(dad === kid); // true


なるほど。
(ちなみに、jQueryのextendメソッドは深いコピーを作成してくれるらしい。)
(jQueryであるならそちらを使えば良い。でも原理を知っておくことは重要だ。)

◆ミックスイン

function mix() {
var arg,
prop,
child = {};

for (arg = 0; arg < arguments.length; arg++) {
for (prop in arguments[arg]) {
if (arguments[arg].hasOwnProperty(prop)) {
child[prop] = arguments[arg][prop];
}
}
}

return child;
}

var child = mix(
{a: 1, b: 2},
{c: 3},
{d: 4, e: 5, f: 6}
);

console.dir(child); // a = 1, b = 2, c = 3, d = 4, e = 5, f = 6



◆まとめ

「コードの再利用こそがゴールであり、継承はそのゴールに到達するためのひとつの手段にすぎません」
[PR]
by redchant | 2011-03-05 21:22 | Computer
ウズラ本 第5章「オブジェクト作成のパターン」 復習編


勉強の進捗により、随時更新。

◆名前空間
名前空間とは、JavaScriptで書くと次の例のようなもので、Javaでいうところのpackageか。
ライブラリを組むとなったら必須の知識だ。(そして僕はライブラリを組むのが夢だ。)

var MYAPP = MYAPP || {};
MYAPP.jp = MYAPP.jp || {};
MYAPP.jp.exblog = MYAPP.jp.exblog || {};
MYAPP.jp.exblog.redchant = MYAPP.jp.exblog.redchant || {};


見てのとおり冗長だが、汎用の名前空間作成関数の例がある。
上記と同じことをする。

var MYAPP = MYAPP || {};

MYAPP.namespace = function(ns_string) {
var parts = ns_string.split("."),
parent = MYAPP,
i;

if (parts[0] === "MYAPP") {
parts = parts.slice(1);
}

for (i = 0; i < parts.length; i++) {
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}

return parent;
};

var module = MYAPP.namespace("jp.exblog.redchant");
console.log(module === MYAPP.jp.exblog.redchant); // true


とってもスマートだ。


◆プライベートなプロパティとメソッド
Javaではprivateやらpublicやらでデータを公開するしないを決められる。
JavaScriptでこれを実現するとなると少し手間がかかる。(それも慣れの問題かと思われる)
その手間っていうのはクロージャで実現するということからだ。
次の例はJavaScriptの単純な例、すべてパブリックだ。

var Data = function(name) {
this.name = name;
this.getName = function() {
return this.name;
};
};

var redchant = new Data("redchant");
console.log(redchant.name); // redchant
console.log(redchant.getName()); // redchant


nameプロパティをプライベートにしたい。

var Data = function(name) {
this.getName = function() {
return name;
};
};

var redchant = new Data("redchant");
console.log(redchant.name); // undefined
console.log(redchant.getName()); // redchant


nameプロパティが非公開になりました。
getNameメソッドのようにプライベートなメンバにアクセスできるメソッドを、この本では特権メソッドと呼んでいる。

・プライバシーの侵犯
次の場合、オブジェクトを返す、つまり参照を返すのでプライベートにならない。
JavaScriptでは、数値、真偽値、文字列の3つのプリミティブは値渡し、
オブジェクト(もちろん関数含む)は参照渡しだ。

function Gadget() {
var specs = {
x: 100,
y: 200
};

this.getSpecs = function() {
return specs;
}
}

var g = new Gadget(),
specs = g.getSpecs();

// gの内部を変えるつもりじゃなかったのに!
specs.x = 300;
specs.y = 400;

// 変わってしまった!
console.dir(g.getSpecs()); // x = 300, y = 400


この解決には、オブジェクトの複製を行うことでできるらしい。次の章でやるらしい。

・プロトタイプ
サイ本で散々勉強したのでprototypeについては大丈夫なんだけど、一応。
上の例でGadgetのインスタンスを10000個作成した場合、
(specsオブジェクトは個々のデータなのでともかく、)
getSpecsメソッドもメモリに10000個ロードしてしまう。
これはあまりに非効率であるのでprototypeに作成するべき。

function Gadget() {
var specs = {
x: 100,
y: 200
};
}
Gadget.prototype.getSpec = function() {
return this.spec;
};


詳しくは「サイ本」、もしくは「Java開発者のための Ajax実践開発入門」が良い。


◆モジュールパターン
名前空間オブジェクトを作ってその中にメソッドを格納する、ということでよいのかな?

var MYAPP = MYAPP || {};
MYAPP.util = MYAPP.util || {};
MYAPP.util.array = MYAPP.util.array || {};

MYAPP.util.array = (function() {

// 1回だけ行ういろんな初期化処理
// ・・・

var inArray = function() {
console.log("inArray was called");
};
var isArray = function() {
console.log("isArray was called");
};

return {
inArray: inArray,
isArray: isArray
};
}());

MYAPP.util.array.inArray(); // inArray was called
MYAPP.util.array.isArray(); // isArray was called




◆サンドボックスパターン
やっぱり難しい。ここまでするか、と思った。
まあ、グローバル空間を汚さないための1つの例として受け止めました。


◆静的メンバ
・プライベートな静的メンバ
パブリックな静的メンバには興味は湧かず。
プライベートな静的メンバとは、クロージャで実現する。
この本によると定義は次のようになる。
●同じコンストラクタ関数で作成されたすべてのオブジェクトで共有される。
●コンストラクタの外部からはアクセス出来ない。

var Gadget = (function() {

// counterが静的変数
var counter = 0,
NewGadget;

NewGadget = function() {
counter += 1;
};

NewGadget.prototype.getLastId = function() {
return counter;
};

return NewGadget;

}());

var iphone = new Gadget();
console.log(iphone.getLastId()); // 1

var ipod = new Gadget();
console.log(ipod.getLastId()); // 2

var ipad = new Gadget();
console.log(ipad.getLastId()); // 3


難しいなあ、クロージャ。
つまりは、関数ローカルスコープでデータを管理することと理解しているが。


◆オブジェクト定数
「オブジェクト定数」というより、「定数オブジェクト」だと思う。

var constant = (function(

var constants = {},
ownProp = Object.prototype.hasOwnProperty,
allowed = {
string: 1,
number: 1,
boolean: 1
};

return {
// 定数定義、セット関数
set: function(name, value) {
if (this.isDefined(name)) {
return false;
}
if (!ownProp.call(allowed, typeof value)) {
return false;
}
constants[name] = value;
},
// 定数が定義されているか関数
isDefined: function(name) {
ownProp.call(constants, name);
},
// 定数ゲット関数
get: function(name) {
if (this.isDefined(name)) {
return constants[name];
}
return null;
};
};

) {}());

constant.isDefined("max_width"); // false

constant.set("max_width", 480); // false

constant.isDefined("max_width"); // true

constant.get("max_width"); // 480


callについては要復習だ。
でも、なんでわざわざcallを使うのかなあ。

[疑問]
コンストラクタ関数がなんなのか、よくわからなくなった。。。

おお、第3章がまさにそういう内容だったような。復習だあ。

次の例がほぼ同義。

// オブジェクトリテラル
var o1 = {
name: "redchant",
getName: function() { return this.name; }
};

console.log(o1.getName()) // redchant

// コンストラクタ
function Func() {
this.name = "redchant";
this.getName = function() { return this.name; };
}
var o2 = new Func();

console.log(o2.getName()) // redchant




(了)
[PR]
by redchant | 2011-03-01 22:17 | Computer
jQueryの楽しさ
いま、jQueryを勉強しています。

c0050550_2384681.jpg

面白いです。
なにが面白いかって、思い通りに、にゅるにゅると動くのが面白いです
味気ないHTMLがにゅるにゅると。
そして時にはサクっと。
にゅるサク。

僕が初めて扱ったプログラミング言語はVisualBasic6でした。
会社の新人研修で教えてもらったのです。
その時の、驚きと喜びと苦労とを今思い出しています。
モノ(といってもディスプレイ上の)が動いているのを見るのは楽しかったです。
これは(僕が)RubyやPerlを勉強していたときには味わえなかったことでもあります。

そして、改めてユーザインターフェースの重要さを感じさせられます。
人にやさしいインターフェース、これからもどんどん増えていくであろうネット民にはそれが重要です。
(懲りすぎたら自己満だけど)

とにかくjQuery楽しいです♪
しばらくはハマっていそうです。
次はいよいよクックブック!
わかるかなあ(不安
[PR]
by redchant | 2011-02-04 23:09 | Computer
Head First Rails / 関連
きた、難しかった。

第6章 「「つながり」を作る」。

ついに他テーブルと結びつけるシステムを勉強した。
ここ、Railsの難しいところというか慣れが必要なところなんだろうなあ。

書くならなんとかなりそうだけど、
読めと言われたら、よく考えないと読めないなあ。
この章は明日ももう一度勉強しようと思う。

だけど、今までRubyを勉強してきた甲斐あって、
読めないRubyコードは今のところ、この本にはないです。
そこはうれしいところ。
だから、頑張ればRailsも読めるはず。
[PR]
by redchant | 2010-12-21 22:06 | Computer
Head First Rails / SQL、Validator
第4章「データベースファインダ」を勉強した。

ここまでは、単一キー指定でデータ取得→1レコード表示というシンプルな画面を扱っていた。
scaffoldだけで、これが出来てしまうんだから、それだけでもスゴイこととは思っていたが。
でも、心のなかでは、Railsはきっと複数キーの条件にも対応してるんだろなあと思ってました。
で、やっぱり、対応していました。装備していました。

s = params[:search_string]
ClientWorkout.all(:conditions=>["client_name = ? OR trainer = ?", s, s])

んまあ、スゴイです。
パラメータがハッシュで、値の配列の1コ目が条件文字列で、バインド変数(だっけ?)が続くなんて。
Railsを作った人、DHHさん、言わずもがな天才です。


[22:45]

勢いに乗って、第5章も勉強した。
第5章は、「データの検証」、つまり、Validatorについて。
Railsには便利なValidatorが装備されてました。
でも、独自なValidatorを実装したい場合については書かれてなかった。
どうやるんだろう。

まあ、とりあえず、覚えなきゃ。

validates_numericality_of :field1
validates_length_of :field1, :length=>32
validates_format_of :field1, :with=>/regular expression/
validates_uniqueness_of :field1
validates_inclusion_of :field1, :in=[val1, val2, ..., valn]

[PR]
by redchant | 2010-12-18 19:59 | Computer
Head First Rails / 結局CRUDを揃えることになったが、有意義!
第3章 「登録、更新、そして削除」を勉強しました。

まあ、予想は出来ていたことだが、
読込だけでなく、登録、更新、削除の機能を揃えることになりました。

だけど、この章では、どういう風にRailsが動いているのか少し理解が深まりました。少しだけど。
とても詳しく書いてあるし。Railsが親切だし。
まだ、Railsの中身まで探ろうという余裕はまだありません。
そんな楽しみはもう少し先にとって置くカンジで。
[PR]
by redchant | 2010-12-17 22:30 | Computer