Home > programing | javascript | 日記 > JavaScript、クロージャをおさらいしてみる

JavaScript、クロージャをおさらいしてみる

久々のエントリーです。

最近はまったく忙しくて、全然勉強する時間もありゃしません。

弊社の人が作ったJavaScriptでトグル処理をするソースコードがメールで流れてきて それに触発されて、自分もいろいろ書いてみて、社内でシェアしたものをうpします。

まるごとJavaScriptを見ていて、クロージャっていいよね。という気分だったので クロージャをおさらいしてみました。 トグル処理の様々な実装方法テスト in JavaScript

最終的なソースコードはこんな感じになったよ。

/**
 * オブジェクトを継承する(Objectを汚染拡張 from prototype.js)
 * @param destination 拡張されるオブジェクト
 * @param source 雛形オブジェクト
 */

Object.mixin = function( destination, source ){
  for (property in source)
    destination[property] = source[property];
  return destination;
}

/**
 * トグル可能な要素を表すクラス
 */

var TogglableElement = function(){};
TogglableElement.prototype = {
  flag:true,
  resultTarget:undefined,
  toggle:function(){
    this.flag = !this.flag;
  },
  update:function(){
    this.resultTarget.innerHTML = ( this.flag ) ? 'ON' : 'OFF';
  },
  onmouseup:function(){
    this.toggle();
    this.update();
  }
};

/**
 * 初期化
 * イベントハンドラはHTML内ではなく、スクリプト内で定義
 */

function init(){
 
  /* オブジェクト拡張方式 */
  var btn1 = document.getElementById('btn1');
  var btn2 = document.getElementById('btn2');
 
  //  ボタン要素をトグラブルオブジェクトに拡張する
  Object.mixin( btn1, TogglableElement.prototype );
  Object.mixin( btn2, TogglableElement.prototype );
 
  //  出力先を定義する
  btn1.resultTarget = document.getElementById('result1');
  btn2.resultTarget = document.getElementById('result2');
 
  /* クロージャ渡し方式 */
  document.getElementById('btn3').onmouseup = getToggleClosure( document.getElementById('result3') );
  document.getElementById('btn4').onmouseup = getToggleClosure( document.getElementById('result4') );
 
  /* ソースコードの表示トグル */
  document.getElementById('viewsource-a').onclick = getToggleClosure2( document.getElementById('sourcecode-a'), viewSourceCode );
  document.getElementById('viewsource-b').onclick = getToggleClosure2( document.getElementById('sourcecode-b'), viewSourceCode );
  document.getElementById('viewsource-c').onclick = getToggleClosure2( document.getElementById('sourcecode-c'), viewSourceCode );
}

/**
 * トグル処理&DOM操作のクロージャ関数を返す
 * 1つの関数を各所で使い回せるようにクロージャ化する
 * @param target HTMLElement 内容を書き換えるHTML要素
 */

function getToggleClosure( target ){
  var flag = true// フラグ。レキシカルスコープ内に保持
  var target = target;  //  ターゲット。レキシカルスコープ内に保持
  return function(){
    flag = !flag;  //  フラグを逆転
    target.innerHTML = ( flag ) ? 'ON' : 'OFF'; // flag==trueならON
  };
}

function getToggleClosure2( target, callback ){
  var flag = true;
  var target = target;
  var callback = callback
  return function(){
    flag = !flag;  //  フラグを逆転
    callback.apply( this, [ target, flag ] );
  };
}

function viewSourceCode( target, flag ){
  this.innerHTML = ( flag )? 'ソースコードを表示する' : 'ソースコードを隠す';
  target.style.display = ( flag )? 'none' : 'block';
}

/**
 * window.onloadにリスナーを貼る
 */

if( /msie/.test(navigator.userAgent.toLowerCase()) )
  window.attachEvent( 'onload', init );
else
  window.addEventListener( 'load', init, true );

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.func09.com/wordpress/archives/125/trackback
Listed below are links to weblogs that reference
JavaScript、クロージャをおさらいしてみる from func09

Home > programing | javascript | 日記 > JavaScript、クロージャをおさらいしてみる

Search
Feeds
Meta

Return to page top