2009年5月27日水曜日

ハングルで"ジャバスクリプト"

자바스크립트="ジャバスクリプト"
らしい

JavaScript arguments.callee

callee - MDC
現在実行している関数を示します。

無名関数内でcalleeを参照することで
無名関数であっても自身を参照できる

下のように、無名再帰関数を実行することができる

function makeFactorialFunc() {
alert('making a factorial function!');
return function(x) {
if (x <= 1)
return 1;
return x * arguments.callee(x - 1);
};
}

var result = makeFactorialFunc()(5); // 120 (5 * 4 * 3 * 2 * 1) を返す

JavaScript @cc_on

一行で IE の JavaScript を高速化する方法
に@cc_onなんてのがあり
何者なのか調査

MSDNによると
@cc_on ステートメント
は"条件付きコンパイルの機能をアクティブにします。"とのこと
コメント/**/内に記述するので
@cc_onに対応していないブラウザでは、コメントとして無視される

JScriptの実装のようなので
対応するブラウザ=IEのみ
となる
下のようにすれば、IEとIE以外で実行するコードを分けられる

var type;
/*@cc_on
//IEのみ
type = "IE";
*/
//IE以外
type = "NOT IE";

JavaScript グローバル変数へのアクセスとパフォーマンス

一行で IE の JavaScript を高速化する方法
amachang の 「一行で IE の JavaScript を高速化する方法」を掘り下げてみた
などで書かれていたが
document、windowなどのグローバル変数へのアクセスは
パフォーマンスがよろしくない。
(latest logさんの速度比較は大変興味深い)

そこで、グローバル変数をローカル変数に代入し
アクセスする際はローカル変数にアクセスすることで
だいぶパフォーマンスが上がるみたい

var _doc = document;

jQueryでも同様の方法がつかわれている

// Will speed up references to window, and allows munging its name.
window = this,

prototype.jsでは使われておらず
普通にグローバル変数へアクセスしている
こういったあたりでjQueryの方が速度が速かったりしてるんだろう、きっと。

2009年5月26日火曜日

JavaScript 継承とプロトタイプチェイン

JavaScriptがプロトタイプベースのオブジェクト指向言語ってどういうこと?

まずは、擬似的な継承はこんな感じで実現できる

function Hito(name) {
this.name = name;
};
Hito.prototype.hello = function() {
alert('Hello! My name is ' + this.name);
};
function SuperMan(name) {
this.name = name;
}
//Hitoオブジェクトをプロトタイプに設定
SuperMan.prototype = new Hito();

var hulk = new SuperMan('Hulk');
//SuperManにhelloはないがプロトタイプチェインをたどり
//Hitoのhelloが見つかり実行される
hulk.hello();

JavaScriptにおける全てのオブジェクトは
Object.prototypeを継承しています。
・constructor
・toString
・toLocaleString
・valueOf
・hasOwnProperty
・isPrototypeOf
・propertyIsEnumerable
などのメソッドがObject.prototypeに含まれる

後からObject.prototypeに追加もできる

Object.prototype.hoge = function() {
alert('hoge');
}
"text".hoge();

JavaScript prototypeとメモリの関係

下の例では
Hitoコンストラクタから3つのオブジェクトを作成している
コンストラクタ内ではthisを使い、変数・関数を割り当てている
この場合だと、変数・関数ともにそれぞれ別にメモリ上に割り当てられてしまうことになり
メモリの無駄遣いとなる

function Hito(name) {
this.name = name;
this.hello = function() {
alert('Hello! My name is ' + this.name);
};
}
var saito = new Hito('saito');
var ishii = new Hito('ishii');
var kume = new Hito('kume');
saito.hello();
ishii.hello();
kume.hello();


そこでprototypeを使い
下のように書きかえることで
関数が共用されるようになる。

function Hito(name) {
this.name = name;
};
Hito.prototype.hello = function() {
alert('Hello! My name is ' + this.name);
};
var saito = new Hito('saito');
var ishii = new Hito('ishii');
var kume = new Hito('kume');
saito.hello();
ishii.hello();
kume.hello();

JavaScrit スコープチェイン

JavaScriptクロージャを完全理解!スコープチェインを知る
を参考に勉強

ローカル変数を宣言した場合、JavaScript内部では
管理用のハッシュテーブル(変数オブジェクトと呼ぶ)
に格納される。
グローバル変数の場合はwindowオブジェクトのプロパティに格納される
例えば

var hoge = 100;
alert(window.hoge);

という風にwindow.hogeでグローバル変数にアクセスできる

以下例ではグローバル変数にf()からアクセスできる
実行時、順にf()内の変数オブジェクトを検索しaはないので
次にグローバル変数を探し、アクセスしている。(関数外の変数にアクセスできる)
この変数の探索をスコープチェインという

var a = 0;
function f() {
alert(a);
}
f(); // 0が表示される