【JavaScript】function定義方法による動作の差異(覚書)
Javascriptで関数(function)を名前付きで定義したい場合、いろいろな書き方があります。
例えば、
これらは普段、特に意識して区別することなく使用しているのですが、調べてみると定義の仕方で微妙に動作が異なってくるようです(あ、new Function()は私には使いにくくてほとんど使っていないので検証はパス(苦笑))。
例えば→こんな感じ。
例えば、
- function TEST() {alert('TEST')}
- var TEST=function() {alert('TEST')};
- var TEST=function test() {alert('TEST')};
- var TEST=new Function("alert('TEST')");
これらは普段、特に意識して区別することなく使用しているのですが、調べてみると定義の仕方で微妙に動作が異なってくるようです(あ、new Function()は私には使いにくくてほとんど使っていないので検証はパス(苦笑))。
例えば→こんな感じ。
上記のリンク先をIE6/Firefox/Operaで見てみると、それぞれ微妙に動作が異なってiいます(FirefoxとOperaは__parent__プロパティがあるかないかの違いだけなので、本質的なものではありませんが)。
もっとも顕著な違いとしては、
また、
3.(右辺が名前付き関数)の書き方をしたあとで、右辺の関数名(例では'test')をtypeofしてみると、IE6ではfunction、Firefox/Operaではundefinedになる(IE6ではtest()で呼びだし可能、Firefox/Operaでは例外発生)。ってことでしょうかね。
また、
IE6では、3.(右辺が名前付き関数)の前に 1.(通常の名前付き関数)の形式で 3. の右辺と同名の関数(例では'test')が定義されていると、3. によって上書きされてしまう。という現象が発生してしまいます(サンプルの[CASE-2])。 2.のように右辺が無名関数になっていればそんな現象は起らないのですが、うっかり 3. のように右辺に関数名をつけて書いてしまうと、なかなか見つけにくいバグが発生しそうです。
ちなみに、Firefoxでは 3. の書き方をすると、TEST.__parent__が
これから、まず新規に(無名の)Objectを作成し、そのプロパティ(上記例では'test')の値として右辺の関数を設定した後、当該プロパティ(への参照)を左辺に渡す、ということをやっているのではないかと推測されます。
実際、
右辺で名前付き関数を指定した場合、その都度専用の名前空間用オブジェクトが作成されてしまうことになるので(共用はされず、また同名にしても上書きにはならない模様)よほどの理由がない限り、無名関数とした方がよさそうです。
({test:(function test() {p("TEST");})})のように設定されます。
これから、まず新規に(無名の)Objectを作成し、そのプロパティ(上記例では'test')の値として右辺の関数を設定した後、当該プロパティ(への参照)を左辺に渡す、ということをやっているのではないかと推測されます。
実際、
var TEST=(function(){return {test:(function test() {p('TEST');})}.test;})();のようにしてやっても、Firefoxでは 3. の場合と同様の動きになります。
あるいはもっとシンプルに
var TEST={test:function test() {p('TEST');}}.test;
これは 1. の書き方をした場合の関数の名前空間とは独立した名前空間を確保するため、かな?
多分、Operaでも似たようなことをしているのかとは思いますが、Operaは__parent__が無いため検証は出来ませんでした。
なお、FirefoxでTEST.__parent__を調べると、1./2.の場合には、windowオブジェクト(Global領域で定義された場合)もしくはnull(関数内で定義された場合)になります(名前空間用のObjectが新規に作成されるのは、1.~3.では3.のみ)。多分、Operaでも似たようなことをしているのかとは思いますが、Operaは__parent__が無いため検証は出来ませんでした。
右辺で名前付き関数を指定した場合、その都度専用の名前空間用オブジェクトが作成されてしまうことになるので(共用はされず、また同名にしても上書きにはならない模様)よほどの理由がない限り、無名関数とした方がよさそうです。
« 【JavaScript】IE6でTABLE要素内をHTMLで書換える関数 | トップページ | 【JavaScript】これ(this)はなに? »
「パソコン・インターネット」カテゴリの記事
- Twitter 原寸びゅー:PC版ブラウザ用・Twitterの画像閲覧と保存がはかどる拡張機能の紹介(2016.02.12)
- スマートフォンをPC上の音楽を再生するためのリモコンとして使いたい(2016.01.10)
- BIGLOBE光ネクスト(大阪)の通信速度問題 - プロバイダ選びは難しい……(2015.08.13)
- BOOK☆WALKER さんに関して最近経験した不安と不満(2015.08.10)
- 『#鳥獣戯画制作キット』が楽しい(2015.07.01)
「覚書」カテゴリの記事
- 鍛高譚 ~ カレイにまつわる物語(2018.05.25)
- ココログをTwitterカードに対応させてみる(2016.11.23)
- 神使の兎 ~宇治神社にて~(2016.07.10)
- Twitter 原寸びゅー:PC版ブラウザ用・Twitterの画像閲覧と保存がはかどる拡張機能の紹介(2016.02.12)
- スマートフォンをPC上の音楽を再生するためのリモコンとして使いたい(2016.01.10)
« 【JavaScript】IE6でTABLE要素内をHTMLで書換える関数 | トップページ | 【JavaScript】これ(this)はなに? »
コメント