1

これはおそらく、Javascript を初めて使用する人にとって典型的な質問です。同様の質問をいくつか調査しましたが、私が見ている動作を説明できませんでした。

以下のコードは、私がやろうとしていることを示しているはずです。MyObjectA と MyObjectB の 2 つのオブジェクトがあります。

MyObjectB には、echo単にメッセージをログに記録するメソッドがあります。this.name誰がメソッドを実行しているかを知るために、メッセージの前にを付けます。の値も出力しますthis

MyObjectA には、callAFunctionWithMessageまさにそれを行うメソッドが呼び出されています。メッセージと関数を受け取り、それを呼び出します。

グローバル スコープでは、オブジェクトがインスタンス化されて呼び出されます。私が見るものはthis.nameですundefined。そして、ブラウザで実行するとthis価値がありDOMWindowObject、nodejsで実行すると大規模なインフラストラクチャのようなオブジェクトがありました。誰かがこの行動についての洞察を手伝ってくれますか? MyObjectA がエコーを呼び出していることを考えると、'this' が MyObjectA を指すと予想していました。

また、予想どおり、MyObjectB.echo('hello')どこthisが MyObjectB を指すかを実行します。

function MyObjectA(name) {
    this.name=name;
}

MyObjectA.prototype = {
    name : "",
    callAFunctionWithMessage: function (msg, callback) {
        callback(msg);
    }
}

function MyObjectB(name) {
    this.name = name;
    }

MyObjectB.prototype = {
    name :"",
    echo: function(msg) {
        var messageToPrint='[from '+this.name+']'+msg;
        console.log(messageToPrint, " : " + this);
    }
}

var a = new MyObjectA("ObjA");
var b = new MyObjectB("objB");

a.callAFunctionWithMessage('hello from A!', b.echo);
// => [from result]hello from A! : [object Window]

b.echo('hello!');
// => [from objB]hello! : [object Object]
4

3 に答える 3

3

あなたがするとき:

a.callAFunctionWithMessage('hello from A!', b.echo);

関数b.echoはグローバルコンテキスト(あなたの場合はウィンドウ)で渡されます。sothis.nameはオブジェクトの name プロパティにはなりませんが、グローバル コンテキストaのプロパティになるため、未定義として表示されます。代わりに、 function.bindを使用してそれ自体nameのコンテキストで呼び出すように変更できます。a

 a.callAFunctionWithMessage('hello from A!', b.echo.bind(a)); //now you set the callback with the context of b itself.

あなたの場合、コールバックメソッド内thisがグローバルスコープを表す場合。

フィドル

または、現在のコンテキストを設定してコールバックを呼び出す方法を変更し、コンテキストがバインドされていないコンテキストを取得するようにします。

MyObjectA.prototype = {
    name : "",
    callAFunctionWithMessage: function (msg, callback) {
        callback.call(this, msg);
    }
}

フィドル

于 2013-09-23T16:13:49.820 に答える
2

コールバックとして渡す場合b.echo、そのコンテキストを失う関数を渡します。this意味を知るための簡単なルールがいくつかあります。

  1. オブジェクト コンテキストでは、オブジェクト インスタンスを参照します。
  2. オブジェクト コンテキストの外では、グローバル オブジェクト (ウィンドウ) またはundefined厳密モードに依存します。
  3. 厳密モードが有効な場合this、自動的にグローバル オブジェクトに解決されません。となりますundefined
于 2013-09-23T16:16:30.993 に答える
1

thiswillの値は、関数がどのように呼び出されるか、つまり呼び出し時にどのコンテキストが与えられるかによって変わります。これに対する唯一の例外は、バインドされた関数です。

次の例が理解に役立つことを願っていますthis

function foo() {
    console.log(this);
}

var bar = {
    'foo': foo,
    'baz': function () {foo();}
};

foo();       // -- logs the global object
             //    `foo` was called without context
bar.foo();   // -- logs `bar`
             //    `foo` was called with context `bar`
bar.baz();   // -- logs the global object
             //    `baz` (in context `bar`) called `foo` without context
var x = bar.foo;
x();         // -- logs the global object
             //    `x` was called without context, `x` is still `foo`
x.call(bar); // -- logs `bar`
             //    `x` was called with context `bar`
于 2013-09-23T16:18:29.230 に答える