code up

スポンサーサイト

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

undefinedを引数に指定する

jQueryのgitリポジトリにあるソースを眺めていたらふと疑問がわいた。引数にundefinedを指定している?

引数にundefinedをつける理由

(function( window, undefined ) {
// ...省略
})( window );

jQueryに限らずよく見かける手法なので何か理由があるのだろうと調べたらJavaScript function with 'undefined' parameter - Stack Overflowでヒントを見つけた。

Stack Overflowの回答および、そこでポイントされていたPaul Irish氏のビデオ; 10 Things I Learned from the jQuery Source(4:15から7:35あたり)を見ると次のような理由から使用を推奨しているようだ。

  • 別のスクリプトでundefinedに違う値を指定していても動作が保証される。nullは予約後なので値を代入することができないが、undefinedはできてしまう

    undefined = true;
  • ローカル変数になるので、スコープチェインの探索(Scope Chain Traversal)時間が短縮される。ほんっとにわずかなパフォーマンス向上-_-;

  • YUI CompressorGoogle Closure Compiler等でminifiedした時にローカル変数名が短縮されるので圧縮効率があがる

    (function(window, undefined){
      if(window!==undefined){
        console.log(window);
      }
    })(window);
    ↓ minified (Online Google Closure Compiler; Optimization: Simple)
    (function(a,b){a!==b&&console.log(a)})(window);
    ↓ minified (Online YUI Compressor)
    (function(a,b){if(a!==b){console.log(a)}})(window);

ってことはjQueryのプラグインは

jQueryのプラグイン作成のページによるとjQueryプラグイン自身はself invoking(executing) anonymous function(自己実行クロージャ)で作成することを推奨している。

(function($){

)(jQuery);

Paul Irish氏のポイントを加えると、次のように書くのがトレンドだろう。

(function($, undefined){

)(jQuery);

jQuery UIのコードを見てみると、($, undefined)となっていた。

nullとundefined

[JavaScript] typeof arg == 'undefined' っていらないんじゃね? - LiosK-free Blog(2008年の記事ですが)という意見がある。

ようはnullとundefinedは暗黙の型変換で同一値となる、ということ。

null == undefined
null === null
undefined === undefined
undefined == null

がtrueとなる。

jQueryやjQuery UIコードを見てもtypeof foo !== 'undefined'という記述はほとんど無く、foo !== undefinedfoo != nullという記述が多い(変数fooがはっきりしている場合; そうじゃないとTypeError/ReferenceErrorが出る)。

しかしDOMのプロパティなどブラウザによっては存在しないプロパティの存在を確認する時は、typeof div.style.zoom !== 'undefined'などと使っている。

jQueryではおそらく下記のように使い分けているのではないかなーと。

typeof foo.bar !== 'undefined'
fooにbarプロパティが存在するかの確認(fooは、null、undefined以外である)。
foo.bar !== undefinedでも記述可、jQuery UIではfoo.bar !== undefinedという記述の方が多い。
foo != null
fooがnullかundefinedの場合。
foo !== null
fooがはっきりとnullでない場合。
foo !== undefined
引数や変数の確認の処理でよく使用されている。
例えば関数でfoo(bar)としていて、第一引数がない場合(foo()あるいはfoo(undefined)と呼ばれた場合)。
引数がある場合はsetter、無い場合はgetterとして動作する$.fn.text()とか$.fn.data()で利用されている。
でも、この使い方はfoo(undefined)も引数なしと同一視されるため、$.fn.val()のようにarguments.lengthで判断すればいいんじゃないか、という気がするが他に理由があるのかも。
jQuery UIではプロパティや属性の存在確認でもこの記法が多い。
!foo
falseでもundefinedでもnullでも''でも0でもいい場合。フラグ系とか正規表現の結果とか、私は一番良く使う方法。

私が他によく使う方法としては、

if(typeof Deferred !== 'undefined'){
  Deferred.define();
}

というようにグローバル変数に外部のライブラリ(上記はjsDeferredというJavaScriptの非同期処理ライブラリ)が展開済みかを確認する際にもtypeof foo !== 'undefined'を利用している。

その他

調べている過程でPaul Irish氏のスライドショー; jQuery Anti-Patterns for Performance & Compressionを見つけた。スライドショーだけで説明がないので、分からないスライドもあるが、いくつものTipsが詰まっている。あと先ほど紹介したビデオ; 10 Things I Learned from the jQuery Sourceも50分以上あるが、見応えがありそう(最初の10分で中断中^^;)

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