web-dev-qa-db-ja.com

hasOwnPropertyがオブジェクトのプロトタイプの関数を認識しないのはなぜですか?

JavaScriptのhasOwnPropertyメソッドは、現在のタイプのプロパティのみを識別するために存在することを理解していますが、ここのプロトタイプチェーンには、混乱を招くものがあります。

ボブと呼ばれる型を定義し、2つの異なる方法で2つの子関数をボブ型に割り当てると想像してみましょう。

_function Bob()
{
    this.name="Bob"; 
    this.sayGoodbye=function()
    {
        console.log("goodbye");   
    }
}

Bob.prototype.sayHello= function()
{
    console.log("hello");   
}
_

sayGoodbyeの場合にクロージャスコープにアクセスできることを除けば、Bobクラスに属する両方の関数は多かれ少なかれ等しいはずだと私には思えます。ただし、hasOwnPropertyでそれらを探すと、JavaScriptに関する限り同じではありません。

_var myBob = new Bob();
console.log( myBob.name ); // Bob, obviously 
console.log( myBob.hasOwnProperty("sayHello"));  // false
console.log( myBob.hasOwnProperty("sayGoodbye")); // true
console.log( "sayHello" in myBob ); // true
_

範囲の観点からここで何が起こっているのですか? sayHello()プロパティとsayGoodbye()プロパティを接続せずに、Bobタイプのインスタンスを作成できなかったので、プロトタイプメソッドがこれまでのところ二級市民である理由hasOwnPropertyが関係しているように? _Bob.prototype_は、Bobがすべてを継承する、Bob型とは独立して存在する型ですか?

12
glenatron

ここでいくつかの概念を混乱させていると思います。 [〜#〜] mdn [〜#〜] からこの引用を取りましょう:

Objectの子孫であるすべてのオブジェクトは、hasOwnPropertyメソッドを継承します。このメソッドを使用して、オブジェクトがそのオブジェクトの直接プロパティとして指定されたプロパティを持っているかどうかを判断できます。 in演算子とは異なり、このメソッドはオブジェクトのプロトタイプチェーンをチェックダウンしません。

それがここでの鍵です。 newを使用すると、JavaScriptは新しいオブジェクトをthisに割り当てて返します。これが、インスタンスです。コンストラクター内で宣言されたプロパティはすべて独自のプロパティです。 prototypeで宣言されたプロパティは、同じオブジェクトの他のインスタンスと共有されているため、そうではありません。

また、prototypeObjectでもあります。例:

Bob.prototype.hasOwnProperty("sayHello"); //=> true

myBob.constructor.prototype.hasOwnProperty("sayHello"); //=> true
12
elclanrs

JavaScriptのhasOwnPropertyメソッドは、現在のタイプのプロパティのみを識別するために存在することを理解しています

それは正しくありません。 hasOwnProperty オブジェクトのownプロパティ、つまりオブジェクト自体。オブジェクトの[[Prototype]]チェーンの継承されたプロパティは考慮されません。

例えば.

var foo = {name: 'foo'};

// Check for an own property
foo.hasOwnProperty('name'); // true

オブジェクトfooもObject.prototypeからtoStringメソッドを継承しますが、これは「独自の」プロパティではありません。

typeof foo.toString             // function
foo.hasOwnProperty('toString'); // false
3
RobG