2

理解しなければならないことがあり、質問を伝えるのに役立つようにプランクを作成しました。

JavaScript:

// "person" written as a plain object
var person = {
    showName: function () { return this.name; },
    setName: function (newName) { this.name = newName; }
};

//  room is class where nested function is a lambda
var room1 = {
    capacity: 10,
    exits: 2,
    count: 0,
    person: 'this property is a String, not an Object',
    addPerson: function (name) {
        this.count += 1;
        this.person = name;
        var nestedFunction = function (name) {
            this.person = name + ' name has been blown away';
        }(name);
    }
};

//  room is class where nested function is a method
var room2 = {
    capacity: 10,
    exits: 2,
    count: 0,
    person: 'this property is a String, not an Object',
    addPerson: function (name) {
        this.count += 1;
        this.person = name;
        function nestedFunction(name) {
            this.person = name + ' name has been blown away';
        }(name);
    }
};

HTML:

<input id="PersonObjectButton" type="submit" value="Click Me First to See Person showName Method Called"
           onclick="person.setName('Dave');alert(person.showName());" /> <br /> 
<input id="PersonObjectButtonAwry" type="submit" value="Click Me To Blow Away Global Variable" 
           onclick="room1.addPerson('Alan');alert(person);" /> <br />              
<input id="PersonObjectButtonFine" type="submit" value="Click Me to See Person showName Method Called" 
           onclick="room2.addPerson('Alan');alert(person.showName());" /> <br />  

そのプランクを実行して一番上のボタンを押すと、「Steve」という名前が表示されます。難しいことは何もありません。その下のボタンをクリックすると、「アランは今ここにいます。他の名前は吹き飛ばされました」というテキストが表示されます。私はそれを理解していると思います。基本的に、room1 のnestedFunctionは関数であり、メソッドではありません。これはオブジェクトのメンバーであるメソッドではないため、Global 名前空間にあり、 person変数を吹き飛ばします (したがって、thisキーワードはroom1オブジェクトへの参照を保持しません)。

なかなか辿り着けない3つ目のボタンです。ページを更新して 3 番目のボタンをクリックすると、変数がグローバル名前空間のperson変数を吹き飛ばしていないことがわかります。その場合、thisキーワードはroom1オブジェクトへの参照を保持します。

私の質問は、ネストされているにもかかわらず、関数式として作成されていない名前付きの functionがroom2オブジェクトのメンバーになるのは何ですか? それとも、グローバル変数を吹き飛ばさないのはなぜですか?

4

2 に答える 2

3

これは、nestedFunction 定義と(name)room2 が 2 つの別個のステートメントであるためです。

var nestedFunction = function (name) {
    this.person = name + ' name has been blown away';
}(name);

このコードは関数を作成し、変数名で呼び出し、戻り値を に代入しますnestedFunction

function nestedFunction(name) {
    this.person = name + ' name has been blown away';
}(name);

一方、このコードは名前付き関数を作成します。その操作の戻り値は常に未定義であるため、関数をすぐに呼び出すことはできません。代わりに、2 つの別個のステートメントとして扱われます。

function nestedFunction(name) {
    this.person = name + ' name has been blown away';
};(name);

関数を作成し、変数を評価します!

Javascript コンソールでデモするには:

function nestedFunction(name) {
     console.log("called")
}("example")
// "example"
于 2013-09-05T07:02:11.237 に答える
2

room1すぐに実行される関数式があります( IIFE とも呼ばれますthisグローバルオブジェクトを参照するのは正しいです。したがって

var nestedFunction = function (name) {
    this.person = name + ' name has been blown away';
}(name);

と同等です

window.person = name + ' name has been blown away';

2 番目のケースでは、関数宣言を使用します。見た目はともかく、機能は実行されていません。コードは実際には2 つのステートメントとして解釈されます。

function nestedFunction(name) {
    this.person = name + ' name has been blown away';
} // end of function declaration
(name); // an expression statement which doesn't do anything

と同じです

function nestedFunction(name) {
    this.person = name + ' name has been blown away';
}
name;

あるいは単に

function nestedFunction(name) {
    this.person = name + ' name has been blown away';
}

私の質問は、ネストされているにもかかわらず、関数式として作成されていない名前付き関数について、それをroom2オブジェクトのメンバーにするのは何ですか?

のプロパティ値にはなりませroom2

それとも、グローバル変数を吹き飛ばさないのはなぜですか?

関数が実行されないためです。宣言の後に置くnestedFunction();と、 とまったく同じように動作しroom1ます。

于 2013-09-05T07:02:20.400 に答える