67

私はJavaScriptのプロトタイプの概念にかなり慣れていません。

次のコードを検討します。

var x = function func(){
}

x.prototype.log = function() {
  console.log("1");
}

var b = new x();

私が理解しているように、プロトタイプなb.log()ので1を返す必要があります。xしかし、なぜプロパティがb.prototype未定義なのですか?

関数b.prototypeへの参照を返すことになっていないのですか?x

4

5 に答える 5

77

コンストラクター関数のみがプロトタイプを持っています。xはコンストラクター関数なのでx、プロトタイプがあります。

bコンストラクター関数ではありません。したがって、プロトタイプはありません。

構築した関数b(この場合はx)への参照を取得する場合は、次を使用できます。

b.constructor
于 2013-01-22T02:47:22.290 に答える
24

関数の.prototypeプロパティは、関数がコンストラクターとして呼び出されたときに新しいオブジェクトの継承を設定するためだけにあります。

新しいオブジェクトが作成されると、その内部[[Prototype]]プロパティは、関数の.prototypeプロパティが指すオブジェクトに設定されます。

.prototypeオブジェクト自体はプロパティを取得しません。オブジェクトとの関係は完全に内部的なものです。

それがそれがするために働く理由ですb.log()。JSエンジンは、bオブジェクト自体にlogプロパティがないことを確認すると、オブジェクトの内部オブジェクトを検索しようとします[[Prototype]]。そこで、JSエンジンはオブジェクトを正常に検出します。

明確にするために、[[Prototype]]プロパティは直接アクセスできません。これは、JSエンジンによって提供される他の構造を介して間接的にのみ変更可能な内部プロパティです。

于 2013-01-22T02:49:12.833 に答える
15

JavaScriptのすべての通常のオブジェクトには、内部プロトタイプスロットがあります(注:ここでのプロトタイプは、プロトタイププロパティを参照していません)。ECMAScript標準(http://www.ecma-international.org/ecma-262/6.0/index.html)は、このスロットが[[Prototype]]と呼ばれることを指定しています。このスロットには、__proto__プロパティを介してアクセスできます。

__proto__は、ブラウザ間で確実に利用できない場合があります。__proto__はECMAScript6の公式プロパティになります

ただし、プロトタイププロパティは、構築されたオブジェクトの__proto__プロパティになるものを設定するコンストラクター関数のプロパティです。

特定のタイプのプロトタイププロパティにアクセスできます。たとえば、コアJavaScriptタイプ(Date、Arrayなど)にアクセスできます。また、JavaScript関数(コンストラクターと見なすことができます)には、パブリックプロトタイププロパティがあります。ただし、関数のインスタンスにはプロトタイププロパティがありません。

あなたの場合var b = new x();、、bは関数xのインスタンスです。したがって、b.prototypeは未定義です。ただし、bには内部[[Prototype]]スロットがあります。b.__proto__Google Chrome(バージョン63.0.3239.132など)またはFirefox(バージョン43.0.4など)で出力する場合

console.log(b.__proto__);

[[Prototype]]スロットは次のように表示されます。

{log: ƒ, constructor: ƒ}

それでおしまい。


参考までに、コードスニペット全体を次のように配置します。

var x = function() {
};
x.prototype.log = function() {
  console.log("1");
}

var b = new x();
b.log();  // 1

console.log(b.prototype); // undefined
console.log(b.__proto__); // {log: ƒ, constructor: ƒ}
console.log(x.prototype); // {log: ƒ, constructor: ƒ}
于 2016-02-08T23:57:00.913 に答える
14

コードを実行する前に、コードの動作を理解するために必要なプロトタイプの概念を確認したいと思います。

  1. [[prototype]]はJavaScriptオブジェクトの非表示プロパティです。この非表示プロパティは、Object.prototype(オブジェクトリテラルによって作成された場合)へのリンクにすぎません。この[[prototype]]プロパティにアクセスする標準的な方法はありません。
  2. JavaScriptの関数はオブジェクトであるため、[[prototype]]プロパティもあります。ここで、関数の場合、この非表示のプロパティはへのリンクです。このプロパティFunction.prototypeにアクセスする標準的な方法もありません。[[prototype]]
  3. この隠しリンクとは別に[[prototype]]、関数オブジェクトが作成されるたびに、prototype隠しプロパティとは別のプロパティがその中に作成され[[prototype]]ます。

今あなたのコードに来ています:

var x = function func(){}

この行が実行されると、関数オブジェクトxが2つのリンクで作成されます。

  • Function.prototype(アクセス不可)、
  • x.prototype(アクセス可能)。

x.prototype.log = function(){console.log( "1"); }

xこれは関数オブジェクトであるためアクセス可能であることがわかっているx.prototypeので、ここでlogメソッドを含めることができます。

var b = new x();

bはオブジェクトですが、関数オブジェクトではありません。その隠しリンク[[prototype]]がありますが、アクセスできません。b.prototypeそのため、結果として得られるようにアクセスしようとするとundefined、のプロトタイプを確認したい場合は、bが表示(x.prototype).isPrototypeOf(b);されますtrue。したがって、非表示のリンクはに参照されていると言えますx.prototype

プロトタイプに関するいくつかの事実は次のとおりです。

  1. オブジェクトOがで作成された場合O = new func(){}、O[[prototype]]はFunction.prototypeです。
  2. オブジェクトOがで作成された場合O = {}、O[[prototype]]はObject.prototypeです。
  3. オブジェクトOがで作成された場合O = Object.create(obj)、O[[prototype]]はobjです。
于 2014-09-15T15:21:41.297 に答える
1

は関数(実際にはコンストラクター)のプロパティであるためprototype、このクラスのオブジェクト(このプロトタイプが属するコンストラクターから作成されたもの)のプロパティ/メソッドを定義するためです。このリンクを見てください

于 2013-01-22T02:46:33.380 に答える