3

重複の可能性:
なぜ this.defineProperty() (オブジェクトの場合) ではなく Object.defineProperty() なのですか?

特定のオブジェクトのすべてのメソッドは、実際のオブジェクト インスタンスから、つまりオブジェクトを引数としてobject.method();渡すことによって呼び出すことができることに気付きました。Object.method()例えば:

var a = ['one', 2, 3, 'four'];
a.reverse();
// OR
Array.reverse(a);

私は同じ振る舞いをしたように見えました。私は違いが何であり、一方が他方よりもいつ使用されるのか疑問に思っていましたか?

4

1 に答える 1

6

Object.method(o)Objectオブジェクト ( ObjectJavaScript では実際のオブジェクト) で呼び出されたプロパティを検索しmethod、変数を渡してそれを呼び出そうとしますo。通話中は、thisになりますObject

o.method()oは、呼び出されたプロパティの変数によって参照されるオブジェクトを調べ、method何も渡さずにそれを呼び出そうとします。呼び出し中thiso.

ご覧のとおり、彼らはまったく異なることをしています。

特定のオブジェクトのすべてのメソッドは、実際のオブジェクト インスタンスから、またはオブジェクトをObject.method()引数として渡すことによって呼び出すことができることに気付きました。

いいえ、できません。あなたの例は、呼び出されるプロパティがないため、関数として呼び出すことができないためArray.reverse(a)、の標準実装で失敗します。編集:Firefoxのスクラッチパッドで動作することをコメントで指摘しましたが、私はそれを確認しました。これは、Firefox の SpiderMonkey JavaScript エンジンが、 の静的実装を提供する非標準の拡張機能を適用していることを意味します。これは Firefox に固有のものであり、すべてのオブジェクトに一般的なものではありません。(たとえば、独自の を作成した場合、そのプロトタイプ関数も魔法のように追加されません。)ArrayArrayreverseArrayreverseArrayFooFoo

ほぼ同等のものを作成する標準的なa.reverse()方法は、次のようにプロトタイプを使用することです。

Array.prototype.reverse.call(a);

それ標準のエンジンで機能します。それでは、それが何をするか見てみましょう:

  1. prototypeからプロパティを取得しますArray

  2. reverse#1で取得したオブジェクトからプロパティを取得します。

  3. Function#callJavaScript 関数オブジェクトの機能を使用してプロパティが参照する関数を呼び出し、関数呼び出しの過程でthis渡される引数にします。call

配列を作成すると、オブジェクトは基礎となるプロトタイプを取得します。そのプロトタイプはArray.prototype、新しい配列が作成されるときに参照されるオブジェクトです。基になるプロトタイプにプロパティがあるため、Soaにはプロパティがあります。reversereverse

これを行うと、次のようになりa.reverse()ます。

  1. reverseオブジェクトからプロパティを取得しaます。(通常)aと呼ばれる独自のプロパティを持たないためreverse、標準の JavaScript プロパティ ルックアップはaの基礎となるプロトタイプを参照します。そこでプロパティを見つけ、その値を使用します。

  2. this呼び出し内にあるように機能aする呼び出し。

ご覧のとおり、基本となるプロトタイプが同じオブジェクトを参照していれば、最終結果は同じです。(そうしないことは可能ですが、または他の組み込みの場合、誰かが[ augmentingではなく]を置き換えた場合、それは Bad Thing (tm)になります。)aArray.prototypeArrayArray.prototype

于 2012-12-16T11:20:48.203 に答える