2012-11-27 13 views
5

これはChromeのバグやSafari/Firefoxの寛容さと考えられますか?クロージャーの名前は内部で同じ名前の関数と衝突しますが、Chromeの場合のみ

私はクロージャー関数を作成するときに、任意の名前 "Button"を与えます。クロージャ内には、クロージャが作成する主オブジェクト(「ボタン」とも呼ばれる)のコンストラクタである関数があります。

クロージャは、Buttonへの参照を返します。おそらく内部関数Button()です。

var closure = (function Button(){ 

    //the closure's primary object 
    function Button(target) { 
     //constructor for our button object 
    } 

    Button.prototype = e.inherit(e.Plugin.prototype); 
    Button.prototype.constructor = Button; 

    return { 
      Button: Button, 
     }; 

}()); 

//now let's call our closure to create a new Button 
var newButton = new closure.Button() 

SafariとFirefoxでは、これは問題ではありません。新しいclosure.Button()を呼び出すと、内側のButton()のインスタンスが返されます。しかし、クロムでは、内部関数名がクロージャー関数名と一致すると、コンストラクターは呼び出されないように見えます。返されるのはクロージャー関数そのもののようです。これはもちろん、内部関数が後で呼び出すメソッドを定義するときにエラーに繋がります。

私は二つの理由から、この質問を投稿しています:

1)これは、Chromeは(に私のボタンは、メソッドの.activateを持っていないことを報告された、問題の原因を見つけるために、私に1日以上かかりました実際のコードでは、Buttonは.activate()メソッドを提供する親オブジェクトから継承します)。他の誰かがこの問題に遭遇した場合、彼らはここで私の質問を見つけ、時間を節約するかもしれません。

2)これは私のところではエラーですが、クロージャーとクロージャー内の機能の両方に同じ名前を使用すると、Safari/Firefoxではどうして機能していますか?具体的には、クロムは実際に何らかの形でクロージャが意図した内部関数ではなく、それ自身を返すようにしていますか?これはバグですか?

+6

クロムにはreproがありません:http://jsfiddle.net/77LZh/ –

+0

IEの名前付き関数式に関する問題について聞いたことがあります([here](http://kangax.github.com/nfe/) )が、Chromeでは使用できません。実際、@ SeanKinseyのテストはChromeでうまくいくようです。あなたはコンストラクタが呼び出されていないと思いますか? – bfavaretto

答えて

1

おそらく正確な問題ではありませんが、不必要に関数式の名前を付けました。

var closure = (function Button(){ 

    //the closure's primary object 
    function Button(target) { 
     //constructor for our button object 
    } 

    Button.prototype = e.inherit(e.Plugin.prototype); 
    Button.prototype.constructor = Button; 

    return { 
      Button: Button, 
     }; 

}()); 
//now let's call our closure to create a new Button 
var newButton = new closure.Button() 

var closure = (function(){ 

    //the closure's primary object 
    function Button(target) { 
     //constructor for our button object 
    } 

    Button.prototype = e.inherit(e.Plugin.prototype); 
    Button.prototype.constructor = Button; 

    return { 
      Button: Button 
     }; 

}()); 

//now let's call our closure to create a new Button 
var newButton = new closure.Button(); 

トップレベル関数が名前であることである差であるべきです。あなたは再び使うことのない何かを命名する必要はありません。

また、戻りオブジェクト内にカンマを使用しないでください。これは構文エラーとして出現するはずです。

また、最後の行にはセミコロンがありません。

+0

これは助けにはならない - JavaScriptの語彙的スコープは、これが問題にならないようにする。コマンドとセミのニットは十分に正しいですが、この問題には慎重ではありません。 –

+0

@SeanKinsey私はそれを助けと呼んでいません。あなたの権利は、あなたが再現できない問題を解決するのは難しいです。私はガマットを実行しようとしていました。 – dqhendricks