0

http://jsfiddle.net/ZLH7J/1/

以下のjsFiddleとコードが示すのは、本質的に同じことを行う2つの例です。呼び出しようとするとfirst();、またはthis.first();いずれかの例で、未定義のエラーがスローされます。init(){...}()後でインスタンスを介して関数を呼び出すことはできますが、コンストラクターのようにオブジェクトをインスタンス化しようとするときはできません。init()を操作の順序だと思って一番下に置きましたが、そうではありません。これは、私が思っていたようには機能しません。

私はこれがどのように行われるべきか、そしてなぜこれができないのかを理解することに興味があります。

//create and return an obj
var fishSticks = function(){
    return {
        first: function(){
            document.getElementById('output').innerHTML="Success";
        },
        init: function(){
            try{
                first(); //err
                this.first(); // also err
             }catch(e){
                document.getElementById('output').innerHTML=e.toString();
            }
        }()
    }
}   

//do function stuff and then return 'this'
var fishFillet = function(){
    var first = function(){
            document.getElementById('output2').innerHTML="Success";
    }
    var init = function(){
            try{
                first(); //err
                this.first(); // also err
             }catch(e){
                 document.getElementById('output2').innerHTML=e.toString();
            }
    }()
return this;
}

 var test = new fishSticks();    
 var test2 = new fishFillet();

</ p>

4

4 に答える 4

1

2番目の例では、「init」の呼び出しをコメントアウトするとthis.first()、「Success」メッセージが表示されます。

最初のバージョンは機能しません。JavaScriptでは、構築中のオブジェクト内でオブジェクト自体への参照を作成できないためです。それを行う方法はありません。

「first」はローカル変数として宣言されているため、2番目のものは機能します(「first」への単純な参照は機能します)。ローカル変数はどのオブジェクトのプロパティでもありません。特に、関数がで呼び出されたときに割り当てられたオブジェクトのプロパティではありませnewthis.first()それが機能しない理由です。

this.first()2つ目では、別の方法で宣言することで作業を行うことができます。

var fishFillet = function(){
    this.first = function(){
            document.getElementById('output2').innerHTML="Success";
    }
    var init = function(){
            try{
                this.first(); //will work
             }catch(e){
                 document.getElementById('output2').innerHTML=e.toString();
            }
    }()
    return this;
}

また、その価値については、の奇妙なアンチパターン

var something = function() { ... }

ほど有用ではありません

function something() { ... }

var宣言の代わりに宣言を使用する理由はありませんfunction

于 2012-08-14T13:04:04.780 に答える
1

2つのことを理解する必要があります。

this1)JavaScriptは、Javaのように自動的に挿入されないため、first()呼び出しは、の定義について字句スコープを調べるだけfirstで、オブジェクトをnokで調べthisます。したがって、への呼び出しは機能するfirst()はずthisですが、内部で期待するもの以外のものにバインドされますfirst

2)コンストラクター内のローカル変数は、構築されたオブジェクトのメンバーにはなりません。

于 2012-08-14T13:05:48.927 に答える
1

どうですか...

var fishFillet = function () {
    var first = function () {
        document.write( 'Success' );
    };

    var init = function () {
        first();
    };

    init();

    return {
        first: first
    };
};

その後:

var ff = fishFillet(); // calls init() which calls first()
ff.first(); // call first() manually

ライブデモ: http: //jsfiddle.net/uaCnv/

したがって、最初にすべての関数を定義し、次に手動でを呼び出しinit、最後に、結果のオブジェクトを介して(メソッドとして)使用できるはずの関数を含むオブジェクトを返します。

于 2012-08-14T13:07:06.807 に答える
1

両方をコンストラクターとして使用しているため、次のようにフォーマットします。

function fishFillet(){
    this.first = function(){
        document.getElementById('output2').innerHTML="Success";
    }
    this.init = function(){
        try{
            this.first();
        }catch(e){
            document.getElementById('output2').innerHTML=e.toString();
        }
    }
}
var food = new fishFillet();
food.init();

それが機能しなかった理由は、b / c "first"がローカル変数として作成され、実行後に削除されるためです。Initは、コンストラクターの実行が終了するまで呼び出されません。

于 2012-08-14T13:07:56.673 に答える