スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JavaScriptで、Hoge instanceof Hoge が成り立つオブジェクトを作る

MozillaのJavaScriptエンジンはStopIterationというオブジェクトを持っている。

try {
  throw StopIteration;
} catch (e if e instanceof StopIteration) {
}

興味深いのは、このStopIterationというオブジェクトについて、StopIteration instanceof StopIteration === trueが成り立つことだ。このような性質を持つオブジェクトを自分で作り出すことはできるのだろうか?

できる。__proto__があれば。

// Firefox、Safari、Chrome、Operaで動作を確認
var f = function(){};
f.__proto__ = f.prototype;
f instanceof f; // ⇒ true

ただし、このfとStopIterationとでは、typeofした時の値(typeof StopIterationはobject)と、呼べるかどうかが異なる。

スポンサーサイト

テーマ : プログラミング | ジャンル : コンピュータ

ブラウザ間のDOM CSSの差異を吸収する

最近、CSS3の2D Transformsを使ってみた。当初はWebKit専用(-webkit-付き)で書いてたんだが、JavaScriptから制御しようと思うとWebKitCSSMatrixがWebKitにしかないので、Firefoxなどの他のブラウザではJavaScriptが動かなくなる。CSS宣言なら単純に無視されるだけなので、これは好ましくない。調べてみると、Mozillaも2D Transformsを実装してるらしい。ならそれを使えばいいじゃん、となるのだが、コードで分岐するのは面倒だ。そこで、こんな感じのコードを書いた。

if (navigator.userAgent.indexOf("Gecko") != -1) {
  CSSStyleDeclaration.prototype.__defineGetter__("transform",function() {
    return this.MozTransform;
  });
  CSSStyleDeclaration.prototype.__defineSetter__("transform",function(x) {
    this.MozTransform = x.toString();
  });
  CSSMatrix = function() {
    /*略*/
  };
  CSSMatrix.prototype = {
    /*略*/
  };
}
if (navigator.userAgent.indexOf("WebKit") != -1) {
  CSSStyleDeclaration.prototype.__defineGetter__("transform",function() {
    return this.webkitTransform;
  });
  CSSStyleDeclaration.prototype.__defineSetter__("transform",function(x) {
    this.webkitTransform = x;
  });
  CSSMatrix = WebKitCSSMatrix;
}

このコードを読み込んでおけば、JavaScriptからの操作は、2D Transformsのドラフトにあるような方法でできる。 ただ、CSSに書くプロパティ名はどうしようもない。

一応完全なコードも以下に載せておく。

続きを読む

テーマ : プログラミング | ジャンル : コンピュータ

JavaScriptで配列を走査するためのオススメの方法: Array.prototype.forEach

今さらだが、Array.prototype.forEachが便利だ。いいところ:

  • タイプ量
    for (var i = 0; i < arr.length; ++i) {
      // 好きな処理
    }
    arr.forEach(function(value,i) {
      // 好きな処理
    });
    比べてみると、Array.prototype.forEachを使うほうが短い。
  • 変数が使い回されない(重要)
    for (var i = 0; i < arr.length; ++i) {
      arr[i].addEventListener("click",function(){
        alert(i);
      },false);
    }
    とか
    for (var i = 0; i < arr.length; ++i) {
      for (var i = 0; i < arr2.length; ++i) {
        // 処理
      }
    }
    が意図通り動かなくて悩んだ人も(俺だけかもしれないけど)多いはず。Array.prototype.forEachを使えばその問題がない。

もちろんfor文を使ったほうが速いんだけど、速度が第一でない限りこっちを使うべきだと思う。

テーマ : プログラミング | ジャンル : コンピュータ

プロフィール

minoki

Author:minoki
好きなプログラミング言語:
Haskell,Lua
GitHubアカウント
Twitter

最新記事
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。