1

与えられた:

var x = function () {
};

x.prototype = {
    y: {
        z: function () {
            console.log(this);
        }
    }
};

var foo = new x();
foo.y.z();

の代わりにとしてthisログインするのはなぜですか?コンストラクタなしのリテラルオブジェクトが与えられる可能性はどのようにありますか?consoleyxy

4

3 に答える 3

2

「なぜこれがxではなくyとしてコンソールに記録されるのですか...」

それがJavaScriptの仕組みだからです。値は、thisメソッドが呼び出されたオブジェクトとして設定されます。通常、オブジェクトは。から遠ざける必要があります.prototype。これらは、コンストラクターを使用して作成されたすべてのインスタンス間で共有されます。


「...そして、yがコンストラクターのないリテラルオブジェクトであるとすると、どうしてそれが可能になるのでしょうか?」

それは簡単です。値はthisコンストラクターに関連付けられていません。これは、関数またはメソッドの呼び出し方法に基づいて設定される動的な値です。


this呼び出しで設定された自然値を手動でオーバーライドできるユーティリティがあります。の.callまたは.applyメソッドを使用してメソッドFunction.prototypeを呼び出すことは一例です

var foo = new x();
foo.y.z.call(foo);

に最初の引数として渡すことで手動で設定したためthiszメソッドにはオブジェクトが含まれます。foo.call

この.callメソッドは、メソッドのメソッドとして呼び出されたことを認識しているzため、自動的に呼び出しますが、最初の引数として指定した値に値をz設定します...この場合はオブジェクトです。thiszfoo


ただし、通常、オブジェクトをの値として使用することはありません.prototype。その理由は、コンストラクターから作成されたすべてのインスタンスがコンストラクターのの暗黙の参照を取得するため、.prototypeのプロパティのオブジェクトへの更新が.prototypeすべてのインスタンスから監視されるためです。

于 2013-02-06T01:40:42.370 に答える
1

これを機能させるにyは、同封のを返す必要がありますthis

var x = function () {};
Object.defineProperty(x.prototype, "y", { get: function() { return this; } })
x.prototype.y.z = function () { console.log(this); }

var foo = new x();
foo.y.z(); // x

.の左側にあるものは何でもz()ですthis。あなたの質問でyは、オブジェクトリテラルを返します:{z:function(){...}}

于 2013-02-06T01:44:17.177 に答える
0
var y=Object.create({z: function () { console.log(this); }});
var x=Object.create(y);
y.z();
x.z();

コンストラクターを使用する代わりに、Object.createを使用してオブジェクトを作成できます。

于 2013-02-06T03:20:29.463 に答える