2009年5月28日木曜日

HTML DOCTYPEについて

DOCTYPE宣言はHTML、XHTMLがどのような仕様に沿って記述しているかを宣言する。
具体的には下記のように書く

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

ブラウザによって解釈は異なるが
基本的に
HTMLタグ以前にDOCTYPの宣言があれば
Stdrds="標準モード"=CSS 仕様に従った正しい解釈をするモード
で
・DOCTYPE宣言がない
・スペルミス、記述が省略されている
などの場合は
Quirks="互換モード"=
として解釈(レンダリング)される

また、XHTMLの宣言をする場合
通常,<?XML ...を一番先頭に記述するが
IE6ではこの記述がDOCTYPEより前にあるとQuirksモードとして
判断されてしまうのでXML宣言は省略して書く(エンコードがUTF-8であれば省略してもOKということになっている)

補足:XHTMLを使う場合の注意点

各部ブラウザのモードの識別については
ここなどにまとめられている
DOCTYPE スイッチについてのまとめと一覧表 (HTML 5 や IE 8 Beta 2 のモードスイッチなどの情報も含んだ 2008 年版 )

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();