これは非常に単純なプロトタイプ ベースのオブジェクト モデルであり、説明中のサンプルと見なされますが、まだコメントはありません。
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ではobjectsとthisキーワードがすべてです。
最初の質問は、 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このオブジェクトには、独自の内部プロトタイプ。等々。