匿名関数に割り当てられた変数が定義されていない

グローバル変数の使用を最小限に抑えるために、変数に割り当てられた無名関数を使用しています。この関数には、画像のプリロードとサイズ変更のためのネストされた関数と、ナビゲーションのためのネストされた2つの関数(次と前)があります。次のコードは、匿名関数が割り当てられている変数が定義されていないというエラーを生成します。 未定義のプロパティ 'preload_and_resize'を読み取ることはできません  あなたが問題を見つけたら、私に知らせてください。どうもありがとうございました。

<html>
<head>
<script type="text/javascript">
var runThisCode=(function(){
 var myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 var imageObj = new Array();
 var index=0;
 var preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };
})();
</script>
</head>
<body onload="runThisCode.preload_and_resize();">
<div align="center">

PrevNext </div> </body> </html>
1

5 答え

あなたの無名関数は何も返さないので、それを実行するとundefinedが返されます。そのため、 runThisCode は定義されていません。それにもかかわらず、あなたが書いた方法で、 preload_and_resize ローカルになりますので、アクセスすることはできません。

代わりに、この無名関数がオブジェクトを構築し、そのをreutrnしたいとします。このような何かがうまくいくか、少なくともあなたを近づける:

var runThisCode=(function(){
 var result = {};
 result.myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 result.imageObj = new Array();
 result.index=0;
 result.preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i< result.myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

    document.pic.style.height=(document.body.clientHeight)*0.95;
};
 result.next_image=function(){
    index++;
    if(index=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };

 return result;
})();
2
追加された
@Neil - それは良い試みだった - あなたはそれほど離れていなかった。
追加された 著者 Adam Rackis,
@ SLaks - ありがとう、変更されました
追加された 著者 Adam Rackis,
@Neil - はい、すべてのコードを公開しました。その関数内で何かをvarとして宣言すると、ローカル(プライベート)になります。結果オブジェクトにはアクセスできますが、外部にはアクセスできません
追加された 著者 Adam Rackis,
ローカル、プライベートではありません。
追加された 著者 SLaks,
@ニール:配列とインデックスを非公開にしておき、必要に応じて機能を公開することができます。 Adam Rackis:+1。
追加された 著者 RightSaidFred,
@アダムありがとう、アダム。これは、 var myImages = new Array( "img//01.jpg"、 "img//02.jpg"、 "img/03.jpg")のようにグローバル変数を避けるための不器用な試みでした。 var imageObj = new Array(); var index = 0; あなたの助けに基づいて修正しようとします。
追加された 著者 Neil Ostridge,

これは間違っていることを説明する必要があります:

var foobar = (function (){
   var priv1, priv2 = 'sum' , etc;
   return {
      pub_function: function() {},
      another: function() {
          console.log('cogito ergo ' + priv2 );
      }
   };

})();

foobar.another();
2
追加された

関数を変数 next_image に割り当てました。この変数は、自己呼び出し匿名関数のスコープです。

runThisCode に割り当てる値は、( return 文がないので)その undefined である匿名関数の戻り値です。

コードを動作させるには、オブジェクトを runThisCode に割り当て、 next_image をそのメンバーにする必要があります。

匿名関数の最後に以下を追加します。

return {
    "next_image": next_image
}
0
追加された

匿名関数を削除し、関数を公開します。グローバル変数は、 runThisCode というオブジェクトのみを作成します。

var runThisCode = function() {
    var myImages = new Array("img/01.jpg", "img/02.jpg", "img/03.jpg");
    var imageObj = new Array();
    var index = 0;
    this.preload_and_resize = function() {
        var i = 0;
        var imageArray = new Array();
        for (i = 0; i < myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src = myImages[i];
        }

        document.pic.style.height = (document.body.clientHeight) * 0.95;
    };
    this.next_image = function() {
        index++;
        if (index < imageObj.length) {
            document.pic.src = imageObj[index].src;
        } else {
            index = 0;
            document.pic.src = imageObj[index].src;
        }
    };
    this.prev_image = function() {
        index--;
        if (index >= 0) {
            document.pic.src = imageObj[index].src;
        } else {
            index = myImages.length - 1;
            document.pic.src = imageObj[index].src;
        }
    };
};

そして、あなたのコードの後ろに:

runThisCode.preload_and_resize();

うまくいくはずです。

0
追加された
私はjavascriptでクロージャーが何かを知りません。
追加された 著者 tereško,
このようなプロパティを使用するには、(new runThisCode).preload_and_resize()のように runThisCode をコンストラクタとして呼び出す必要があります。コンストラクタを再度実行しない限り、他のメソッドにアクセスすることはできません。これは望ましくないでしょう。
追加された 著者 RightSaidFred,

body onloadプロパティにある呼び出しから、IIFEで達成しようとしているように見えます(すぐに呼び出される関数式)は、メソッド preload_and_resize を持つオブジェクトを返します。

他の人が指摘しているように、あなたはIIFEから何も返さないので、本当に起こっているのは、それ自身の名前空間でその中のすべてを閉じていて何かを "エクスポート"していないということです。

これらの関数をIIFEから「エクスポート」したい場合は、最終的なビットを次のように追加します。

return { 
    'preload_and_resize': preload_and_resize, 
    'next_image': next_image,
    'prev_image': prev_image
}

基本的に新しいJavaScriptオブジェクトリテラルを作成し、そのプロパティをローカルスコープの関数値に割り当てます。

いくつかの開発者は、このような冗長性があり、この種の明示的なエクスポートで終了するのではなく、オブジェクトリテラルを宣言している間に関数を定義するだけで済むでしょう。

return { 
    preload_and_resize: function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i=0){
            document.pic.src=imageObj[index].src;
        }
        else {
            index=myImages.length-1;
            document.pic.src=imageObj[index].src;
        }
    }
}
0
追加された
@ Adam、@ SLaks、@ RightSaidFred、@ mc10、@ Weston C、@ Quentinありがとうございました。あなたが提案したように、私はreturn文を追加しました - それは私が逃した最も重要なものでした! - それがうまくいった。私は匿名関数をそれぞれの入れ子関数が割り当てられている各varに対して3つのプロパティを持つリテラルオブジェクトを返すようにしましたが、今あなたのコメントとコードを読んで、冗長性と醜さがあります。再度、感謝します!
追加された 著者 Neil Ostridge,
詳細な説明をありがとう
追加された 著者 Neil Ostridge,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript