ラベル JavaScript の投稿を表示しています。 すべての投稿を表示
ラベル JavaScript の投稿を表示しています。 すべての投稿を表示

2012年12月17日月曜日

CSS3のtransitionで中断と再開を実装してみた


transitionとは
CSS3になって、アニメーションのエフェクトを簡単に実現する機能が出てきました。

その中でもtransitionは、繰り返しのないシンプルなエフェクトを実現します。
簡単な使い方をすると、エフェクト前の状態から何秒かけてエフェクト後の状態に変化させる、というものになります。
これを少し工夫すると、擬似的に変化の中断と再開を実現できます。

このエントリの目次
  1. jsdo.itに置いています
  2. jsdo.itのサンプル
  3. ロジックの概要
  4. さいごに
1.jsdo.itに置いています
こちらです。
Ubuntu の chrome やiOS、Androidのブラウザで動作確認しています。

2.jsdo.itのサンプル
棒グラフがtransitionプロパティで滑らかに伸びていきます。
「中断」ボタンを押すと、伸びるのが止まります。
「再開」ボタンを押すと、再度伸び始めます。

3.ロジックの概要
前述の通りtransitionは、エフェクト前の状態から何秒かけてエフェクト後の状態に変化させる、というものです。
ここでポイントは、エフェクトの途中で、エフェクト後の状態をリアルタイムに変更できるということです。

例えばある棒グラフがあったとして、最初は横幅0pxから100pxまで、10秒かけて変化させるように設定するとします。
5秒後にはある程度のところまで棒が伸びます。
ここで、そのタイミングで、エフェクト後の状態を0pxにすると、棒グラフは滑らかに逆に0pxまで縮んでエフェクトを完了します。

つまりエフェクト後の状態を、一時停止させたいときの幅に設定すると、エフェクトが中断しているように見えるという訳です。

ちなみにエフェクト後の状態を途中で変更しても、transitionend系のイベントは発行されます。

4.さいごに
今回のエントリは、例えば、画面上部からリストがヌルヌルとアニメーションで出てくるような仕様に適用できると思います。
途中で止めたい時に止められるので。

それでは。

2012年12月3日月曜日

左から 緑〜黄〜赤 に変化する棒グラフをJavaScriptとCSS3で書いてみた


こんな感じのグラフを書いてみた
このエントリの目次
  1. jsdo.itに置いています
  2. 緑、黄色、赤のRGB
  3. RGBで緑、黄色、赤のグラデーションを表すには
  4. JavaScriptとCSS3でグラデーションさせる
  5. さいごに

1.jsdo.itに置いています
こちらです。
Ubuntu の chrome と firefox で動作確認しています。

2.緑、黄色、赤のRGB
RGBは「Red」、「Green」、「Blue」の頭文字を取ったもので、赤緑青がそれぞれ0〜ffの16進数で表現されます。

緑、黄色、赤をRGBで表現すると、
  1. 緑 = #00ff00
  2. 黄色 = #ffff00
  3. 赤 = #ff0000
となります。

3.RGBで緑、黄色、赤のグラデーションを表すには
下の絵のとおりです。



黄色になるところがグラフの丁度真ん中です。

赤は黄色になるまで正比例で0から255に増していき、それ以降はずっと255です。
緑は黄色になるまでずっと255で、それ以降は0から255で正比例で減っていきます。
青はずっと0です。

4.JavaScriptとCSS3でグラデーションさせる
グラデーションはCSS3 の linear-gradient()関数を使っています。
このサイトに詳しく載っています。

JavaScript はRGBを計算するんですが、棒グラフの長さが50%未満のとき と 50%以上のとき、2つの場合に分けて考えます。

50%未満のとき
このときは、右端の色を計算します。
緑と黄色の中間の色になります。

50%以上のとき
このときは、右端が黄色と赤の間の色になるので、それを計算します。
さらにlinear-gradient()関数の性質上、丁度50%のときの黄色が、グラフの全横幅に対してどの割合の位置になるのかを求める必要があるので、それも計算します。


言葉では分かりづらいと思うので、最初にリンクしたjsdo.itを参考にしていただければ。
JavaScript のところにコメントも細かく書いています。

5.さいごに
CSS3は便利ですねー。

何かのお役に立てれば。
それでは。

2012年2月27日月曜日

Firefox の Selenium IDE で XML(HTML)のテストを少しだけ簡単にするユーザー拡張スクリプトを書いてみた

Seleniumとは

Webアプリケーション用のテストツール。
テストケースはhtmlで記述され、<table>タグ内の<tr>タグ1つが、テストの1手順を示すので見た目にも分かりやすい。

と、本ブログのSeleniumの導入に関するリンク集01という記事に書いています。

FirefoxにはSelenium IDEというとても便利なアドオンがあるので、本エントリはそれを使う前提で書きます。

このエントリの目次
1.テストを書くのが面倒くさいと思いました
2.作成したユーザー拡張スクリプト
3.使い方
4.最後に

テストを書くのが面倒くさいと思いました
XMLやHTMLの検証などで、getElementByIdとかgetElementsByTagName を書くとき、コードが長くなるのが面倒くさかったのです。
なので簡単なユーザー拡張スクリプトを書いてテストコードを書く量を減らします。

ちなみに、Selenium のユーザー拡張スクリプト集の中に、XMLの値を検証するスクリプトがあるのですが、どうやら要素と要素名を一緒くたにして検証する仕様のようで、しっくりきませんでした。

作成したユーザー拡張スクリプト
GitHubにあげました。

4つの関数を作成しました。

__getElementsByTagName : getElementsByTagName のラッパ関数(テストコードの文字数を減らす用)
__getElementById : getElementById のラッパ関数(テストコードの文字数を減らす用)
__getXmlValue : XMLやHTMLの要素の値を取得する関数
__getXmlAttribute : XMLやHTMLの要素の属性値を取得する関数

3.使い方
まず、ユーザー拡張スクリプトの使い方から。

先ほどのGitHubのコードをコピペして、user-extensions.jsというファイル名でどこかに保存します。
で、Selenium IDEにて
「オプション」→「設定」→「Selenium Core 拡張スクリプト(user-extensions.js) のパス」
で、ファイルのパスを指定します。
Selenium IDE を再起動したら、指定したユーザー拡張スクリプトが使用できます。

次に、各関数の使い方です。

Selenium IDE での記述で説明します。
※(「コマンド」と「値」は省略します。コマンドは全てgetEvalを使用し、値は何も指定しません。)

__getElementsByTagName
対象 : __getElementsByTagName('要素名')
HTMLCollectionが取得できます。

__getElementById
対象 : __getElementById('要素のid')
HTMLElementが取得できます。

__getXmlValue (名前がいけてないですが、HTMLでも使えます orz)
対象 : __getXmlValue(何らかのHTMLElement)
要素の値が取得できます。

__getXmlAttribute (名前がいけてないですが、HTMLでも使えますorz)
対象 : __getXmlAttribute('属性名', 何らかのHTMLElement)
要素の属性値が取得できます。

以上です。

4.最後に
色々といけてない所があるかもですが、好きに改変して使用して下さい。

2011年8月20日土曜日

JavaScriptでObserverパターンを書いてみた

Observerパターンのサンプルはこちら
http://jsdo.it/windblue/y87e

サンプルの概要としては、
  • 「左のボタン」と「右のボタン」がある
  • 「左のボタン」を押すと、「左のボタン」が大きくなり、「右のボタン」は元の大きさに戻る
  • 「右のボタン」を押すと、「右のボタン」が大きくなり、「左のボタン」は元の大きさに戻る

中規模程度のDHTMLで且つ、ある要素で発生したonclickなどのイベントが他の要素に影響を与えるような場合に使えるのではと思います。
逆に言えばごく簡単なDHTMLには冗長な記述だし、大規模なDHTMLとしてはStateパターンなどを組み合わせるなどしないとつらいと思います。

Observerパターンとは
Observerパターン - Wikipediaを参照してください(手抜き)。

これでif文地獄から抜け出せる
ストレートに書くなら、
if(左のボタンを押されたとき){ doSomething(); }


if(右のボタンを押されたとき){ doSomething(); }

のようなコードになりがちですが、中規模以上のWebアプリなどになると、これではif文地獄になってえらいコトになると思います。

それを避けるために、サンプルでは画面上の要素たちを各モデルに分解して、それぞれのモデル(「左のボタン」モデルと「右のボタン」モデル)に、「左のボタン」を押されたときの挙動、「右のボタン」が押されたときの挙動、を記述していきます。

サンプルコードの簡単な説明
http://jsdo.it/windblue/y87eのソースにもちょこちょこコメントを書いていますが。

各モデルに対し、イベントハンドラを登録。
たとえば、「左のボタン」モデルに対しては「左のボタン」のonclickのイベントハンドラを登録。
そのイベントハンドラが、コントローラの「左のボタン」が押されたよメソッドを呼ぶ。
すると、コントローラは「左のボタン」モデルと「右のボタン」モデルの、「左のボタン」が押されたよメソッドを順番に呼んでいきます。
この順番に呼ぶ部分がObserverパターンです。
で、それぞれのメソッドが全て呼ばれたら、表示を変更するために、コントローラが「左のボタン」モデルと「右のボタン」モデルのonUpdateメソッドを呼んでいきます。

また、各モデルは大本となるモデルクラスを継承しています。
モデルクラスは、コントローラから呼ばれる各モデルのメソッドを全て定義しています。
Javaでいうinterfaceのような役割を持っています。
サンプルでは全て空のfunctionです。
「このモデルではこのメソッドがコントローラから呼ばれても特に何もさせない」という場合、そのモデルではそのメソッドを定義していません。
すると、大本のモデルクラスの空メソッドがコントローラから呼ばれるコトになります(interfaceというよりはabstractって感じですね)。
これにより、
コントローラ「このモデルにメソッドが定義されていないじゃないか!(怒)」
というコトが避けられます。

以上になります。

あと全然関係ないけど
Operaだとなぜかjs do.itのタイトルが編集できませんでした。
なんで!(怒)

2010年11月30日火曜日

JavaScriptが世界制覇しそうな予感

なぜかというと
米Yahoo!で議論された、フロントエンドエンジニアリングの将来(前編)という記事を発見しまして。
サーバサイドのJavaScriptという衝撃的な「node.js」に言及しています。
最近チラホラ聞きます(もっとも、本当に「サーバサイドのJavaScript」程度しか知らないのですが。。)

これはJavaScriptをもっと勉強しておいた方がよさそう。。

2010年10月31日日曜日

JavaScriptでよくある性能劣化ポイント

WEB+DB PRESS vol.59より。
自分のためのメモ代わりとして、気になった部分をピックアップ。

まずポイント列挙
JavaScriptコード上でよく見られる性能劣化ポイント(抜粋)。
以下、まず列挙します。リンクはページ内アンカです。
  1. 意図しない変数のグローバル化
  2. コストの高い配列アクセス方法を利用
  3. try/catchの間違った使用
  4. ブラウザの再描画について

意図しない変数のグローバル化
JavaScriptでは、関数内で変数を参照する際にまず自身のスコープ内を探します。
見つからない場合、入れ子になっている関数であれば外側の関数のスコープをたどっていき、グローバルスコープは必ず最後に探索されます(スコープチェイン)。そのため、グローバル変数を発見するのは時間がかかることになります。
また、「var」をつけずに宣言された変数はグローバル変数となります。
なので、グローバルにする必要のない変数は必ず「var」を付けて宣言しましょう。
関連:JavaScriptのクロージャ、スコープチェインについての記事(World Wide Windblue)

コストの高い配列アクセス方法を利用
配列にアクセスするには、以下の2通りの方法がある。
  1. メソッド呼び出し
    後発で使用追加されたメソッドを呼び出すこと。(Array.pushなど)
  2. プリミティブ操作
    原始的なアクセス方法

プリミティブ操作を使用するほうがパフォーマンスが高くなる。

try/catchの間違った使用
catch節が実行されるたびに新しいスコープが生成・破棄されるため、頻繁に実行されるとパフォーマンスが低下する可能性があります。
入力チェック時などエラー判定をするときなどでも、別の方法があるならtry/catch節を排除することが望ましいケースが多いでしょう。

2010 11/1 追記ここから
実際に試してみる。
エラー判定にtry/catchを使わない場合と使った場合で比較。
比較したブラウザはIE7、Firefox3.6.8、Google Chrome7、Opera10.63。
各検証を10回して平均を取った。

エラー判定にtry/catchを使わない場合。
window.onload = function(){
  var start = new Date();
  for(var i = 0;i < 10000; i++){
    var a = 100;
    if(typeof a === 'string'){
      return a.substring(0, 2);
    }else{
    }
  }
  var end = new Date();
  alert((end - start));
}

1回の実行にかかった平均の時間。
IE…11(ms)
Firefox…0.6
Google Chrome…0
Opera…1.9

エラー判定にtry/catchを使わない場合。
window.onload = function(){
  var start = new Date();
  var a = 100;
  for(var i = 0;i < 10000; i++){
    try{
      a.substring(0, 2);
    }catch(e){
    }
  }
  var end = new Date();
  alert((end - start));
}

1回の実行にかかった平均の時間。
IE…540.7(ms)
Firefox…760.7
Google Chrome…1395
Opera…28.9

(Operaが早すぎて不安です。PCのスペックが低いのも関係あるかもしれません)
2010 11/1 追記ここまで

また、catch節の実行時に生成されるスコープは、ローカルスコープよりも上位に位置します。
そのため、catch節の中で変数を定義することは、それだけで処理のオーバーヘッドになります。

ダメな例。
try{
  ...
}catch(error){
  if(error.code === '500'){
    var c = error.code;
    ...
  }
}

この倍、errorオブジェクトに対する処理は別の関数に委譲するコトでパフォーマンスへの影響を最小限に抑えられる。
関数かされた処理はcatchスコープから呼び出されても、ローカル変数は通常のローカル変数スコープ内に定義されます。
よい例。
try{
  ...
}catch(error){
  handleError(error);
}


ブラウザの再描画について
JavaScriptによりDOM要素の位置やサイズ変更、新たなDOM要素の追加などを行うと、ブラウザはその変更を表示されているWebページに反映しなくてはなりません。
このような場合にブラウザの再描画が発生しますが、再描画に要するコストは高く、頻繁に発生すると深刻なパフォーマンス低下を招きます。
再描画の回数を減らすポイントは次の2点。
  1. DOMに対する「スタイルの取得」と「スタイルの変更」を混ぜない
  2. DOMに対する「スタイルの変更」は短時間ですばやく行う

2009年12月18日金曜日

HTML5のWebストレージについて

HTML5の大きな特徴の一つ、Webストレージについて。

Breaking Out The Edges of The Browser (24WAYS)より、
前半部分のWebストレージについて訳してみました。
間違ってたらすみません!

Webストレージとは
クライアント側にデータを蓄えられる仕組み。
(※ちなみに、似たような機能であるクッキーとの違いは以下に書かれています。
W3C - 『Web Storage』日本語訳 (HTML5.JP))

ドメイン毎に5Mバイト程度のデータを扱える
(ただしこれは推奨なので、実際扱える量は各ブラウザに任される)
Storage supports around 5Mb of data per domain
(the spec’s recommendation, but it’s open to the browsers
to implement anything they like)


Webストレージは2種類ある
  1. セッションストレージ
    ウィンドウが開いている間、同一ドメイン上で利用可能。
  2. ローカルストレージ
    手動で消去するまで、同一ドメイン上で利用可能。

メジャーブラウザの対応状況
  1. 全て対応: Internet Explorer, Firefox, Safari(PC、ケータイ、iPhone)
  2. 一部: Google Chrome (ローカルストレージのみサポート)
  3. サポートしていない: Opera (10.10)
APIのインターフェース
セッションストレージもローカルストレージも同一のインターフェースが提供されている。
  1. setItem(key, value)
  2. getItem(key)
  3. key(index)
  4. removeItem(key)
  5. clear()

例えば以下のように記述する。
localStorage.setItem('name', 'windblue');
alert( localStorage.getItem('name') );

データへのアクセス方法は色々あるよ
例えば、
localStorage.name = "windblue";

としたとき、次のようにnameプロパティにアクセスできる。
  1. localStorage.name
  2. localStorage.getItem(localStorage.key(0))

※keyプロパティはゼロベース。

今は文字列しか格納できない
数値も文字列に変換されて格納される。
Currently all browsers only support storing strings.
This also means if you store a numeric, it will get converted to a string.


Objectも同様に文字列に型変換されてストレージに格納される。
Objectを扱いたいときは、ストレージから取ってきた後に、
JSONパーサで文字列→Objectの変換をすればいい。

2009年11月17日火曜日

関数が定義されるタイミング

[Javascript] 関数宣言の落とし穴 function foo ( ){..} と var foo = function ( ) {..} は動作が違うので要注意!にて勉強になった事。

引用。
function foo( ){ ... }
はコンパイル時に関数が定義されます。

var foo = function( ){ ... };
は代入文の実行時に関数が定義されます。


引用(エラーになるケース)
var foo = new Foo();
foo.greet();

function Foo(){ };
Foo.prototype.greet = function (){ alert('hi') };

var foo = new Foo();
foo.greet();

Foo.prototype.greet = function (){ alert('hi') };
function Foo(){ };


なんでエラーになるのか。
Foo.prototype.greet = ...
は代入文で、実行時に関数が定義されるけど、
その定義がされる前に
foo.greet();
を呼んでしまっているから、という事か。

メソッドの代入は、
クラス宣言をした後、かつ、インスタンスからメソッド呼び出しをする前
にやるべし。

とは、「インスタンスからメソッド呼び出しをする前に代入しなければならず、かつ、可読性のためにクラス宣言の後に代入した方がよい」という事かな?

2009年11月15日日曜日

JavaScriptの関数の呼び出しについて

JavaScriptにて関数を呼び出す方法は4つ。
  1. メソッド呼び出しパターン
  2. 関数呼び出しパターン
  3. コンストラクタ呼び出しパターン
  4. apply呼び出しパターン

1.メソッド呼び出しパターン
関数がオブジェクトのプロパティとして格納されている場合には、メソッドと呼ばれる。
myObject.method();

上記のようにメソッドが呼び出された場合、thisにはそのオブジェクトが格納される。
thisを使って自分自身のオブジェクトコンテキストにアクセスしているメソッドは、
パブリックメソッドと呼ばれる。

2.関数呼び出しパターン
var hoge = func(1);

このパターンで呼び出された関数では、thisにはグローバルオブジェクトがセットされる。
内部関数内でのthisと呼び出し元の外部関数でのthisと同じものを指し示すようにするには以下のようにする。
var myObj = {
    valut:0;
};

myObj.half = function(){
    var that = this;        //thisにはmyObjが格納される。
    var calc = function(){
        that.value = that.value / 2;
        //ここで「this」を使用すると、 calc();が関数呼び出しパターンなので、
        //グローバルオブジェクトがセットされてしまう
    };
    calc();
}
myObj.half();

3.コンストラクタ呼び出しパターン
関数を呼び出す歳に、new演算子が前に付けれていた場合、
新しいオブジェクトが生成されて、thisにはその新しいオブジェクトがセットされる。
そのオブジェクトは、呼び出された関数のprototypeプパティへの隠されたリンクを持っている。
new演算子を付けて呼び出すことを前提とした関数は、コンストラクタと呼ばれる。
var Obj = function(string){
 this.status = string;
}

Obj.prototype.get_status = function(){
    return this.status;
};

var myObj1 = new Obj("myObj1");
alert(myObj1.get_status());        //「myObj1」

var myObj2 = new Obj("myObj2");
alert(myObj2.get_status());        //「myObj2」

var myObj3 = myObj1;               //オブジェクトはコピーではなく、参照渡し
alert(myObj3.get_status());        //「myObj1」

myObj3.status = "myObj3";
alert(myObj3.get_status());        //「myObj3」

alert(myObj1.get_status());        //「myObj3」

4.apply呼び出しパターン
applyメソッドを使うことで、引数を格納した配列を使って関数を呼び出すことができるし、
thisにセットされる値を自由に設定することが可能になる。
applyメソッドには2つのパラメータを指定することができ、
1つ目にはthisをセットしたい値、
2つ目はパラメータの配列である。
var statusObject = {
    status:'hogehoge',
}

var status = Obj.prototype.get_status.apply(statusObject);
//statusは「hogehoge」
//なぜなら、
//Obj.prototype.get_status = function(){
//    return this.status;
//};
//のthisに、statusObjectがセットされたので。
//statusObject.statusは'hogehoge'である。

参考文献など
  1. JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
  2. JavaScriptの再利用とapply(勉強するのが、そんなに偉い訳!?)
参考書籍

2009年11月7日土曜日

JavaScriptのクロージャについての記事


  1. クロージャ@IT戦記

  2. JavaScriptとかPerlとかPHPとかさくらとか勉強する-20080416

JavaScriptのスコープチェインについての確認。

4つのコードを試してみた。

1つ目。
var val = 1;
window.onload = function(){
 var val = 10;
 alert("2回目:" + val);
 (function(){
  var val = 100;
  alert("3回目:" + val);
 })();
 alert("4回目:" + val);
 next();
}

function next(){
 alert("5回目:" + val);
}

alert("1回目:" + val);


上記のようなJavaScriptを実行すると、以下のような挙動を示す。
1回目:1
2回目:10
3回目:100
4回目:10
5回目:1

2つ目
var val = 1;
window.onload = function(){
 val = 10;
 alert("2回目:" + val);
 (function(){
  var val = 100;
  alert("3回目:" + val);
 })();
 alert("4回目:" + val);
 next();
}

function next(){
 alert("5回目:" + val);
}

alert("1回目:" + val);

※1つ目のコードと比べて、
alert("2回目:" + val);
の上のval変数を宣言するときに「var」がないよ。
これを実行すると、下のような挙動。
1回目:1
2回目:10
3回目:100
4回目:10
5回目:10

3つ目。
var val = 1;
window.onload = function(){
 var val = 10;
 alert("2回目:" + val);
 (function(){
  val = 100;
  alert("3回目:" + val);
 })();
 alert("4回目:" + val);
 next();
}

function next(){
 alert("5回目:" + val);
}

alert("1回目:" + val);

※1つ目のコードと比べて、
alert("3回目:" + val);
の上のval変数を宣言するときに「var」がないよ。
これを実行すると、以下のような挙動に。
1回目:1
2回目:10
3回目:100
4回目:100
5回目:1

4つ目。
var val = 1;
window.onload = function(){
 val = 10;
 alert("2回目:" + val);
 (function(){
  val = 100;
  alert("3回目:" + val);
 })();
 alert("4回目:" + val);
 next();
}

function next(){
 alert("5回目:" + val);
}

alert("1回目:" + val);

※1つ目のコードと比べて、
alert("2回目:" + val);

alert("3回目:" + val);
の上のval変数を宣言するときに「var」がないよ。
これを実行すると以下のようになる。
1回目:1
2回目:10
3回目:100
4回目:100
5回目:100

JavaScriptのクロージャ、スコープチェインについての記事での、
このように、変数オブジェクトを外側に向かって次々とたぐり、参照された変数を探していくという仕組みがスコープチェインと呼ばれるものです。

の通りの挙動を示しました。

2009年10月18日日曜日

JavaScriptのクロージャ、スコープチェインについての記事

  1. JavaScriptの変数のスコープについて学ぶ
  2. JavaScriptクロージャを完全理解!スコープチェインを知る(前編)
  3. JavaScriptクロージャを完全理解!スコープチェインを知る(後編)
1.JavaScriptの変数のスコープについて学ぶからの抜粋
JavaSctiptでのグローバル変数の宣言の仕方は2種類ある。
  1. 関数本体の外で、変数宣言を行う。
  2. プログラムのいずれかの箇所で、varキーワードをつけずに変数宣言を行う
i = "global";
var j = "global";

function func() {
    k = "global";
    var l = "local"; // ローカル変数
}

上のようなコードの場合、グローバル変数は、
i, j, k, funcの4つ。
funcは、以下のコードと同等
var func = function() {
  ...
};


関数内のスコープは一つだけ!
関数内のローカル変数は、全て関数の先頭で宣言されたことになる
function test() {
   for (var i = 0; i < 10; i++) {
     // ブロック内でjを宣言
     var j = i;
   }
   // ブロックの外だが、jにはアクセスできる
   alert(j);
}


なので、以下のコードの関数fを実行すると、undefinedになる(if文の中で、vがローカル変数として宣言されているため)。
var v = "global";
function f() {
    alert(v);
    if (!v) {
      var v = "local";
    }
}

2.JavaScriptクロージャを完全理解!スコープチェインを知る(前編)からの抜粋
結論からいうと、JavaScriptにおける変数の宣言と参照とは、
「変数名をキー、変数値を値とした、ハッシュテーブルへの読み書き」である。
ハッシュテーブルとは、文字列をキーとして値を取り出せるデータ構造の事。
そして、JavaScriptのオブジェクトはハッシュテーブルと同等。

変数を宣言すると、変数名をキー、undefinedを値とするエントリが
ハッシュテーブル内に作られる。
変数に値を代入すると、ハッシュテーブル内の値が書き換わる。

以下の図における処理では、JavaScript実行環境の内部では、
目に見えないハッシュテーブルへの読み書きとして扱われる。


このハッシュテーブルの事を、正式には変数オブジェクト(Variable Object)と呼ぶ。

変数オブジェクトは場合に応じて変わる。
例えば、関数宣言の外側、<script>タグの直下で変数を宣言した場合は、
変数オブジェクトはグローバルオブジェクトと同じになります(windowオブジェクトになる)。
<script type="text/javascript">
var a = 100;  // 変数aを初期化
alert(window["a"]); // windowのプロパティを参照。100が表示される

window.a = 200; // windowのプロパティを変更
alert(a); // 変数aの値が200に変更されている
</script>

3.JavaScriptクロージャを完全理解!スコープチェインを知る(後編)からの抜粋
スコープチェインとは
実際は変数を参照するという事は、
その場における変数オブジェクト「だけ」を探す訳ではありません。
var a = 0;
function f() {
  alert(a);
}
f(); // 0が表示される

f()の中から「a」という変数を参照し、値を表示する事が出来ています。
しかし、f()のアクティベーションオブジェクト内には、「a」に対応する変数は存在しないはずですね。

つまり変数「a」は次のように探し出されたという事です。
まずf()における変数オブジェクトの中から、
「a」に対応する変数を探しますが、見つかりません。
そこで、その外側にあるグローバルオブジェクトも探す対象となり、
そこでaが見つけ出されたという訳です。

このように、変数オブジェクトを外側に向かって次々とたぐり、
参照された変数を探していくという仕組みがスコープチェインと呼ばれるものです。

クロージャとは
クロージャとは、
「関数自身が定義された環境を、ローカル変数も含めて持ち運ぶことのできる仕組み (またはそうした関数自体) 」
の事をいいます。
以下コード例。
function createCounter() {
  var n = 0;
  // クロージャを作成して返す
  return function() {
    return n++;
  };
}
// createCounter()を呼び出し、
// 戻り値 (関数オブジェクト) を変数に格納しておく
var counter = createCounter();

alert(counter()); // 0が表示される
alert(counter()); // 1が表示される
...

このようにクロージャは、
「関数呼び出しが終わってもローカル変数を参照し続けられる」
という驚くべき特徴を持っています。


この例では、戻り値となる関数が作成された瞬間に、
変数オブジェクトの連鎖(スコープチェイン)が作成されます。
そのチェインの中には、makeClosure()の変数オブジェクトも含まれており、
ローカル変数vが格納されています。


以上。

その他のシリーズは以下
JavaScriptのイロハ

2009年9月6日日曜日

Expressing roughly, HTML5 realizes Web Application and Semantic Web.

http://www.thinkit.co.jp/article/48/2/
Expressing roughly, HTML5 realizes Web Application and Semantic Web.


The following video is embedded by video tag.
Maybe it works Firefox comparatively new version but not Opera 10.0.
And, some fomouse codecs, such as wmv, mpeg, flv and avi, might not be able to play the video.
A format called Ogg Theora may be used.

I can watch this video by Firefox 3.5 but not Opera 10.0


Web Forms 2.0.
New Function to deel auto-focus and verify require text is input.












Related Posts Plugin for WordPress, Blogger...