2131

私は動的プログラミング言語にはあまり興味がありませんが、かなりの量の JavaScript コードを作成しました。このプロトタイプベースのプログラミングについて、私は本当に理解したことがありません。これがどのように機能するか知っている人はいますか?

var obj = new Object();
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

しばらく前に人々と多くの議論をしたことを覚えています (私が何をしているのか正確にはわかりません) が、私が理解しているように、クラスの概念はありません。それは単なるオブジェクトであり、それらのオブジェクトのインスタンスはオリジナルのクローンですよね?

しかし、JavaScript におけるこの ".prototype" プロパティの正確な目的は何でしょうか? オブジェクトのインスタンス化とどのように関連していますか?

更新:正しい方法

var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!

function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK

また、これらのスライドは非常に役立ちました。

4

26 に答える 26

1815

Java、C#、C++ などの古典的な継承を実装する言語では、クラス (オブジェクトの青写真) を作成することから始めます。次に、そのクラスから新しいオブジェクトを作成するか、クラスを拡張して、拡張する新しいクラスを定義します。元のクラス。

JavaScript では、最初にオブジェクトを作成します (クラスの概念はありません)。次に、独自のオブジェクトを拡張したり、そこから新しいオブジェクトを作成したりできます。難しいことではありませんが、古典的な方法に慣れている人にとっては、少し異質で代謝が難しいものです。

例:

//Define a functional object to hold persons in JavaScript
var Person = function(name) {
  this.name = name;
};

//Add dynamically to the already defined object a new getter
Person.prototype.getName = function() {
  return this.name;
};

//Create a new object of type Person
var john = new Person("John");

//Try the getter
alert(john.getName());

//If now I modify person, also John gets the updates
Person.prototype.sayMyName = function() {
  alert('Hello, my name is ' + this.getName());
};

//Call the new method on john
john.sayMyName();

今までは基本オブジェクトを拡張していましたが、別のオブジェクトを作成してから Person を継承しています。

//Create a new object of type Customer by defining its constructor. It's not 
//related to Person for now.
var Customer = function(name) {
    this.name = name;
};

//Now I link the objects and to do so, we link the prototype of Customer to 
//a new instance of Person. The prototype is the base that will be used to 
//construct all new instances and also, will modify dynamically all already 
//constructed objects because in JavaScript objects retain a pointer to the 
//prototype
Customer.prototype = new Person();     

//Now I can call the methods of Person on the Customer, let's try, first 
//I need to create a Customer.
var myCustomer = new Customer('Dream Inc.');
myCustomer.sayMyName();

//If I add new methods to Person, they will be added to Customer, but if I
//add new methods to Customer they won't be added to Person. Example:
Customer.prototype.setAmountDue = function(amountDue) {
    this.amountDue = amountDue;
};
Customer.prototype.getAmountDue = function() {
    return this.amountDue;
};

//Let's try:       
myCustomer.setAmountDue(2000);
alert(myCustomer.getAmountDue());

var Person = function (name) {
    this.name = name;
};
Person.prototype.getName = function () {
    return this.name;
};
var john = new Person("John");
alert(john.getName());
Person.prototype.sayMyName = function () {
    alert('Hello, my name is ' + this.getName());
};
john.sayMyName();
var Customer = function (name) {
    this.name = name;
};
Customer.prototype = new Person();

var myCustomer = new Customer('Dream Inc.');
myCustomer.sayMyName();
Customer.prototype.setAmountDue = function (amountDue) {
    this.amountDue = amountDue;
};
Customer.prototype.getAmountDue = function () {
    return this.amountDue;
};
myCustomer.setAmountDue(2000);
alert(myCustomer.getAmountDue());

前述のように、Person で setAmountDue()、getAmountDue() を呼び出すことはできません。

//The following statement generates an error.
john.setAmountDue(1000);
于 2011-01-24T03:42:35.727 に答える
1046

すべてのJavaScriptオブジェクトには、値がまたはのいずれかであると呼ばれる内部「スロット」があります。スロットは、JavaScriptエンジンの内部にある、作成したコードから隠されたオブジェクトのプロパティと考えることができます。周囲の角かっこは意図的なものであり、内部スロットを示すECMAScript仕様の規則です。[[Prototype]]nullobject[[Prototype]]

オブジェクトのが指す値は[[Prototype]]、口語的に「そのオブジェクトのプロトタイプ」と呼ばれます。

obj.propNameドット( )または角かっこ( )表記を介してプロパティにアクセスしobj['propName']、オブジェクトにそのようなプロパティが直接ない場合(つまり、独自のプロパティ、を介してチェック可能obj.hasOwnProperty('propName'))、ランタイムは参照されるオブジェクトでその名前のプロパティを検索します[[Prototype]]代わりに。[[Prototype]] また、そのようなプロパティがない場合は[[Prototype]]、順番にチェックされます。このようにして、元のオブジェクトのプロトタイプチェーンは、一致するものが見つかるか、その終わりに到達するまでウォークされます。プロトタイプチェーンの最上位はnull価値です。

[[Prototype]]最新のJavaScript実装では、次の方法でへの読み取りおよび/または書き込みアクセスが可能です。

  1. 演算子(newコンストラクター関数から返されたデフォルトオブジェクトにプロトタイプチェーンを構成します)、
  2. extendsキーワード(クラス構文を使用するときにプロトタイプチェーンを構成します)、
  3. Object.create提供された引数を[[Prototype]]結果のオブジェクトのとして設定します。
  4. Object.getPrototypeOfおよび(オブジェクト作成Object.setPrototypeOfの取得/設定)、および[[Prototype]]
  5. __proto__(4と同様に)という名前の標準化されたアクセサー(つまり、getter / setter)プロパティ

Object.getPrototypeOfオブジェクトにのプロトタイプがある場合の動作が異常Object.setPrototypeOfであるため、、よりも優先されます。__proto__o.__proto__ null

オブジェクト[[Prototype]]は、オブジェクトの作成時に最初に設定されます。

を介して新しいオブジェクトを作成する場合new Func()、オブジェクト[[Prototype]]はデフォルトで、によって参照されるオブジェクトに設定されますFunc.prototype

したがって、すべてのクラス、および演算子で使用できるすべての関数には、独自の内部スロットに加えて名前が付けられたプロパティがあることに注意してください。new.prototype[[Prototype]]「プロトタイプ」という言葉のこの二重の使用は、この言語の初心者の間で際限のない混乱の原因となっています。

コンストラクター関数で使用newすると、JavaScriptで古典的な継承をシミュレートできます。JavaScriptの継承システムは、これまで見てきたように、典型的なものであり、クラスベースではありません。

JavaScriptにクラス構文が導入される前は、コンストラクター関数がクラスをシミュレートする唯一の方法でした。.prototypeコンストラクター関数のプロパティによって参照されるオブジェクトのプロパティは、共有メンバーと考えることができます。すなわち。各インスタンスで同じメンバー。クラスベースのシステムでは、メソッドはインスタンスごとに同じ方法で実装されるため、メソッドは概念的に.prototypeプロパティに追加されます。ただし、オブジェクトのフィールドはインスタンス固有であるため、構築中にオブジェクト自体に追加されます。

クラス構文がない場合、開発者は、従来の継承と同様の機能を実現するために、プロトタイプチェーンを手動で構成する必要がありました。これは、これを達成するためのさまざまな方法の優勢につながりました。

これが1つの方法です:

function Child() {}
function Parent() {}
Parent.prototype.inheritedMethod = function () { return 'this is inherited' }

function inherit(child, parent) {
  child.prototype = Object.create(parent.prototype)
  child.prototype.constructor = child
  return child;
}

Child = inherit(Child, Parent)
const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'

...そしてここに別の方法があります:

function Child() {}
function Parent() {}
Parent.prototype.inheritedMethod = function () { return 'this is inherited' }

function inherit(child, parent) {
    function tmp() {}
    tmp.prototype = parent.prototype
    const proto = new tmp()
    proto.constructor = child
    child.prototype = proto
    return child
}

Child = inherit(Child, Parent)
const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'

ES2015で導入されたクラス構文はextends、JavaScriptで古典的な継承をシミュレートするために、プロトタイプチェーンを構成するための「1つの真の方法」として提供することにより、物事を簡素化します。

したがって、上記のコードと同様に、クラス構文を使用して次のような新しいオブジェクトを作成する場合は、次のようになります。

class Parent { inheritedMethod() { return 'this is inherited' } }
class Child extends Parent {}

const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'

...結果のオブジェクトはの[[Prototype]]インスタンスに設定され、Parentそのインスタンス[[Prototype]]は。になりParent.prototypeます。

最後に、を介して新しいオブジェクトを作成するObject.create(foo)と、結果のオブジェクト[[Prototype]]はに設定されfooます。

于 2009-02-21T13:33:54.193 に答える
195

これは非常に単純なプロトタイプ ベースのオブジェクト モデルであり、説明中のサンプルと見なされますが、まだコメントはありません。

function Person(name){
    this.name = name;
}
Person.prototype.getName = function(){
    console.log(this.name);
}
var person = new Person("George");

プロトタイプのコンセプトを検討する前に、考慮しなければならない重要な点がいくつかあります。

1- JavaScript 関数が実際にどのように機能するか:

最初のステップを踏むには、JavaScript 関数が実際にどのように機能するか、キーワードを使用するクラスのような関数thisとして、または引数を持つ通常の関数として、それが何をし、何を返すかを理解する必要があります。

Personオブジェクト モデルを作成するとします。しかし、このステップでは、 andキーワードを使用せずにまったく同じprototypenewことをしようとしています。

したがって、このステップfunctionsではobjectsthisキーワードがすべてです。

最初の質問は、 keywordを使用せずに keyword がどのようthisに役立つnewかということです。

それに答えるために、空のオブジェクトがあり、次のような 2 つの関数があるとします。

var person = {};
function Person(name){  this.name = name;  }

function getName(){
    console.log(this.name);
}

キーワードを使用せずに、newこれらの関数をどのように使用できるかを説明します。したがって、JavaScript にはそれを行うための 3 つの方法があります。

を。最初の方法は、関数を通常の関数として呼び出すことです。

Person("George");
getName();//would print the "George" in the console

この場合、これは現在のコンテキスト オブジェクトであり、通常は windowブラウザまたは のグローバル オブジェクトGLOBALですNode.js。これは、ブラウザの window.name または Node.js の GLOBAL.name の値が「George」であることを意味します。

b. プロパティとしてオブジェクトにアタッチできます

-これを行う最も簡単な方法は、次のように空のpersonオブジェクトを変更することです。

person.Person = Person;
person.getName = getName;

このようにして、次のように呼び出すことができます。

person.Person("George");
person.getName();// -->"George"

そして今、personオブジェクトは次のようになります:

Object {Person: function, getName: function, name: "George"}

-プロパティをオブジェクトにアタッチするもう 1 つの方法prototypeは、そのオブジェクトの を使用することです。このオブジェクトは、 という名前の JavaScript オブジェクトで見つけることができます__proto__。要約の部分で少し説明しようとしました。したがって、次のようにして同様の結果を得ることができます。

person.__proto__.Person = Person;
person.__proto__.getName = getName;

しかし、この方法で実際に行っているのは の変更です。Object.prototypeリテラル ( ) を使用して JavaScript オブジェクトを作成するたびに{ ... }、 に基づいて作成されるためObject.prototype、 という名前の属性として新しく作成されたオブジェクトに関連付けられるため、__proto__変更すると、前のコード スニペットで行ったように、すべての JavaScript オブジェクトが変更されてしまい、良い方法ではありません。したがって、今より良い方法は次のとおりです。

person.__proto__ = {
    Person: Person,
    getName: getName
};

現在、他のオブジェクトは平穏に保たれていますが、それでも良い方法ではないようです。まだもう 1 つの解決策がありますが、この解決策を使用するには、personオブジェクトが作成されたコード行 ( var person = {};) に戻り、次のように変更する必要があります。

var propertiesObject = {
    Person: Person,
    getName: getName
};
var person = Object.create(propertiesObject);

それが行うことは、新しい JavaScript を作成し、属性Objectにアタッチすることです。したがって、できることを確認するには:propertiesObject__proto__

console.log(person.__proto__===propertiesObject); //true

しかし、ここで注意が必要な点は__proto__、オブジェクトの最初のレベルで定義されているすべてのプロパティにアクセスできることですperson(詳細については概要部分をお読みください)。


ご覧のとおり、これら 2 つの方法のいずれを使用してもthis、オブジェクトを正確に指すことになりpersonます。

c. JavaScript には、関数に を提供する別の方法があり、 callまたはapplythisを使用して関数を呼び出します。

apply() メソッドは、指定された this 値と、配列 (または配列のようなオブジェクト) として提供される引数を使用して関数を呼び出します。

call() メソッドは、指定された this 値と個別に提供された引数を使用して関数を呼び出します。

私のお気に入りのこの方法では、次のように関数を簡単に呼び出すことができます。

Person.call(person, "George");

また

//apply is more useful when params count is not fixed
Person.apply(person, ["George"]);

getName.call(person);   
getName.apply(person);

これら 3 つのメソッドは、.prototype 機能を理解するための重要な最初のステップです。


new2-キーワードはどのように機能しますか?

これは、機能を理解するための 2 番目のステップです。これは.prototype、プロセスをシミュレートするために使用するものです。

function Person(name){  this.name = name;  }
my_person_prototype = { getName: function(){ console.log(this.name); } };

newこのパートでは、JavaScript が実行するすべてのステップを、キーワード andを使用せずに、キーワードprototypeを使用するときに実行しようとしますnew。したがってnew Person("George")Person関数はコンストラクターとして機能します。これらは、JavaScript が 1 つずつ行うことです。

を。まず第一に、空のオブジェクト、基本的には次のような空のハッシュを作成します。

var newObject = {};

b. JavaScript が行う次のステップは、すべてのプロトタイプ オブジェクトを新しく作成されたオブジェクトにアタッチすることです。

ここではmy_person_prototype、プロトタイプ オブジェクトに似ています。

for(var key in my_person_prototype){
    newObject[key] = my_person_prototype[key];
}

プロトタイプで定義されたプロパティを JavaScript が実際にアタッチする方法ではありません。実際の方法は、プロトタイプチェーンのコンセプトに関連しています。


を。&b。これらの 2 つの手順の代わりに、次のようにしてまったく同じ結果を得ることができます。

var newObject = Object.create(my_person_prototype);
//here you can check out the __proto__ attribute
console.log(newObject.__proto__ === my_person_prototype); //true
//and also check if you have access to your desired properties
console.log(typeof newObject.getName);//"function"

getNameこれで関数を呼び出すことができますmy_person_prototype:

newObject.getName();

c. 次に、そのオブジェクトをコンストラクターに渡します。

次のようなサンプルでこれを行うことができます。

Person.call(newObject, "George");

また

Person.apply(newObject, ["George"]);

これは、そのコンストラクター内のthisが作成されたばかりのオブジェクトであるためです。

他のステップをシミュレートする前の最終結果: Object {name: "George"}


概要:

基本的に、関数でnewキーワードを使用すると、それを呼び出すことになり、その関数はコンストラクターとして機能するため、次のように言うと:

new FunctionName()

JavaScript は内部的にオブジェクト、空のハッシュを作成し、そのオブジェクトをコンストラクターに渡します。コンストラクターは、必要なことを何でも行うことができます。これは、そのコンストラクター内のthisが作成されたばかりのオブジェクトであり、もちろんそのオブジェクトを提供するためです。関数で return ステートメントを使用していない場合、またはreturn undefined;関数本体の最後に a を配置した場合。

したがって、JavaScript がオブジェクトのプロパティを検索する場合、最初に行うことは、そのオブジェクトのプロパティを検索することです。そして、[[prototype]]私たちが通常持っているような秘密のプロパティが__proto__あり、そのプロパティは JavaScript が次に見るものです。そして、__proto__それが再び別の JavaScript オブジェクトである限り、独自の属性を持ち、次が null__proto__であるポイントに到達するまで上に移動します。__proto__ポイントは、その__proto__属性が null である JavaScript の唯一のオブジェクトはObject.prototypeobject です。

console.log(Object.prototype.__proto__===null);//true

これが JavaScript での継承のしくみです。

プロトタイプチェーン

つまり、関数にプロトタイプ プロパティがあり、その上で new を呼び出すと、JavaScript は新しく作成されたオブジェクトのプロパティを調べ終わった後、関数のプロパティを調べます。.prototypeこのオブジェクトには、独自の内部プロトタイプ。等々。

于 2014-02-13T19:32:12.300 に答える
79

prototypeクラスを作成できます。使用しない場合prototypeは静的になります。

ここに短い例があります。

var obj = new Object();
obj.test = function() { alert('Hello?'); };

上記の場合、静的関数呼び出しテストがあります。この関数は、obj がクラスであると想像できる obj.test によってのみアクセスできます。

以下のコードのように

function obj()
{
}

obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

obj はインスタンス化できるクラスになりました。obj の複数のインスタンスが存在する可能性があり、それらすべてにtest関数があります。

以上が私の理解です。私はそれをコミュニティ wiki にしているので、私が間違っている場合は人々が私を修正できます。

于 2009-02-21T12:37:10.837 に答える
67

このスレッドを読んだ後、JavaScriptプロトタイプチェーンと混同していると感じ、これらのチャートを見つけました

http://iwiki.readthedocs.org/en/latest/javascript/js_core.html#inheritance *[[protytype]]*および関数オブジェクトの<code>prototype</code>プロパティ

プロトタイプチェーンによるJavaScriptの継承を示す明確なグラフです

http://www.javascriptbank.com/javascript/article/JavaScript_Classical_Inheritance/

これには、コードといくつかの優れた図を含む例が含まれています。

プロトタイプチェーンは最終的にObject.prototypeにフォールバックします。

サブクラスのプロトタイプを親クラスのオブジェクトと等しく設定することにより、プロトタイプチェーンを技術的に必要なだけ拡張できます。

JavaScriptプロトタイプチェーンを理解するのにも役立つことを願っています。

于 2012-11-07T09:48:11.940 に答える
30

Javascript には通常の意味での継承はありませんが、プロトタイプ チェーンがあります。

試作チェーン

オブジェクト内にオブジェクトのメンバーが見つからない場合、プロトタイプ チェーン内で探します。チェーンは他のオブジェクトで構成されています。__proto__特定のインスタンスのプロトタイプには、変数を使用してアクセスできます。javascript ではクラスとインスタンスに違いがないため、すべてのオブジェクトに 1 つあります。

関数/変数をプロトタイプに追加する利点は、すべてのインスタンスに対してではなく、一度だけメモリ内に置く必要があることです。

プロトタイプチェーンは他の多くのオブジェクトで構成できるため、継承にも役立ちます。

于 2009-02-21T12:41:31.667 に答える
22

この「.prototype」プロパティの正確な目的は何ですか?

標準クラスへのインターフェースが拡張可能になります。たとえば、Arrayクラスを使用していて、すべての配列オブジェクトに対してカスタム シリアライザーも追加する必要があるとします。サブクラスのコーディングに時間をかけますか、それともコンポジションを使用しますか? プロトタイプ プロパティは、ユーザーがクラスで使用できるメンバー/メソッドの正確なセットを制御できるようにすることで、これを解決します。

プロトタイプは追加の vtable-pointer と考えてください。一部のメンバーが元のクラスから欠落している場合、プロトタイプは実行時に検索されます。

于 2009-02-21T12:37:38.370 に答える
20

The Definitive Guide to Object-Oriented JavaScript - 非常に簡潔で明確な約 30 分のビデオによる、質問された質問の説明 (プロトタイプの継承のトピックは5:45から始まりますが、ビデオ全体を聞きたいと思います)。このビデオの作成者は、JavaScript オブジェクト ビジュアライザーの Web サイトhttp://www.objectplayground.com/も作成しました。ここに画像の説明を入力 ここに画像の説明を入力

于 2016-02-18T15:17:09.760 に答える
14

コンストラクターがオブジェクトを作成するとき、そのオブジェクトは、プロパティ参照を解決する目的で、コンストラクターの「プロトタイプ」プロパティを暗黙的に参照します。コンストラクターの「プロトタイプ」プロパティは、プログラム式constructor.prototypeによって参照でき、オブジェクトのプロトタイプに追加されたプロパティは、継承を通じて、プロトタイプを共有するすべてのオブジェクトによって共有されます。

于 2010-02-05T18:42:10.047 に答える
10

JavaScriptプロトタイプベースの継承をより良い写真で説明する別の試み

単純なオブジェクトの継承

于 2015-10-24T21:21:40.537 に答える
10

keyValueStore次のオブジェクトを検討してください。

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
        this.get = function(key) { return this.data[key]; };
        this.set = function(key, value) { this.data[key] = value; };
        this.delete = function(key) { delete this.data[key]; };
        this.getLength = function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  { // Singleton public properties
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();

これを行うことで、このオブジェクトの新しいインスタンスを作成できます。

kvs = keyValueStore.create();

このオブジェクトの各インスタンスには、次のパブリック プロパティがあります。

  • data
  • get
  • set
  • delete
  • getLength

keyValueStoreここで、このオブジェクトのインスタンスを 100 個作成するとします。、getsetはこれら 100 個のインスタンスのそれぞれに対してまったく同じことを行いますがdeletegetLengthすべてのインスタンスにはこの関数の独自のコピーがあります。

getここで、 、setdeleteおよび のgetLengthコピーを1 つだけ持つことができ、各インスタンスが同じ関数を参照する場合を想像してみてください。これにより、パフォーマンスが向上し、必要なメモリが少なくなります。

そこでプロトタイプの出番です。プロトタイプは、継承されますがインスタンスによってコピーされないプロパティの「青写真」です。したがって、これは、オブジェクトのすべてのインスタンスに対してメモリ内に 1 回だけ存在し、それらのすべてのインスタンスによって共有されることを意味します。

ここで、keyValueStoreオブジェクトをもう一度考えてみましょう。次のように書き換えることができます。

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
    };

    kvs.prototype = {
        'get' : function(key) { return this.data[key]; },
        'set' : function(key, value) { this.data[key] = value; },
        'delete' : function(key) { delete this.data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  {
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();

keyValueStoreこれは、すべてのメソッドがプロトタイプに入れられることを除いて、オブジェクトの以前のバージョンとまったく同じです。これが意味することは、100 個のインスタンスすべてが、それぞれ独自のコピーを持つのではなく、これら 4 つのメソッドを共有するようになったことです。

于 2016-03-11T19:24:36.867 に答える
9

概要:

  • 関数は JavaScript のオブジェクトであるため、プロパティを持つことができます
  • (コンストラクター) 関数には常にプロトタイプ プロパティがあります。
  • newキーワードを使用して関数をコンストラクターとして使用すると、オブジェクトはプロトタイプを取得します。このプロトタイプへの参照__proto__は、新しく作成されたオブジェクトのプロパティにあります。
  • このプロパティは、コンストラクタ関数のプロパティ__proto__を参照します。prototype

例:

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

let me = new Person('willem');

console.log(Person.prototype) // Person has a prototype property

console.log(Person.prototype === me.__proto__) // the __proto__ property of the instance refers to prototype property of the function.

これが役立つ理由:

Javascript には、 「プロトタイプ継承」と呼ばれるオブジェクトのプロパティを検索するメカニズムがあります。基本的には次のようになります。

  • 最初に、プロパティがオブジェクト自体に配置されているかどうかがチェックされます。その場合、このプロパティが返されます。
  • プロパティがオブジェクト自体に配置されていない場合、「プロトチェーンを登る」ことになります。基本的に、protoプロパティによって参照されるオブジェクトを調べます。そこで、 protoによって参照されるオブジェクトでプロパティが使用可能かどうかを確認します。
  • プロパティがprotoオブジェクトに配置されていない場合は、protoチェーンを Object オブジェクトまで上ります。
  • オブジェクトとそのプロトタイプ チェーンのどこにもプロパティが見つからない場合は、undefined が返されます。

例えば:

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

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);

アップデート:

この __proto__プロパティは廃止されましたが、最新のブラウザのほとんどに実装されていますが、プロトタイプ オブジェクト参照を取得するより良い方法は次のとおりです。

Object.getPrototypeOf()

于 2018-08-18T10:24:20.757 に答える