これは非常に単純なプロトタイプベースのオブジェクトモデルであり、説明中にサンプルと見なされますが、まだコメントはありません。
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
console.log(this.name);
}
var person = new Person("George");
プロトタイプの概念を検討する前に、考慮すべき重要な点がいくつかあります。
1- JavaScript関数が実際に機能する方法:
最初のステップを実行するには、JavaScript関数が実際にどのように機能するか、thisキーワードを使用するクラスのような関数として、または引数を持つ通常の関数として、何をして何を返すかを理解する必要があります。
Personオブジェクトモデルを作成するとします。しかし、このステップでは、キーワードを使用せずに、まったく同じことprototypenewを実行しようとしています。
したがって、このステップfunctionsではobjects、thisキーワードがすべて揃っています。
最初の質問は次のようになりますどのようにthisキーワードを使用することなく、有用である可能性newのキーワードを。
そのため、空のオブジェクトと次のような2つの関数があるとします。
var person = {};
function Person(name){ this.name = name; }
function getName(){
console.log(this.name);
}
そして今、使用しなくてもnewキーワードを、私たちは、これらの機能を使用することができますか。したがって、JavaScriptには次の3つの方法があります。
a。最初の方法は、関数を通常の関数として呼び出すことです。
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オブジェクトの第1レベルで定義されているすべてのプロパティにアクセスできることです(詳細については、概要部分を参照してください)。
ご覧のthisとおり、これらの2つの方法のいずれかを使用すると、personオブジェクトが正確に示されます。
c。JavaScriptには、関数thisを呼び出すための別の方法があり、callまたはapplyを使用して関数を呼び出します。
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機能を理解するための重要な最初のステップです。
2- newキーワードはどのように機能しますか?
これは、.prototype機能を理解するための2番目のステップです。これは、プロセスをシミュレートするために使用するものです。
function Person(name){ this.name = name; }
my_person_prototype = { getName: function(){ console.log(this.name); } };
この部分では、newキーワードprototypeを使用するときに、キーワードand を使用せずに、JavaScriptが実行するすべての手順を実行しようとしていますnew。そのためnew Person("George")、Person関数はコンストラクタとして機能します。JavaScriptが実行する処理は次のとおりです。
a。まず、空のオブジェクト、基本的には次のような空のハッシュを作成します。
var newObject = {};
b。JavaScriptが実行する次のステップは、すべてのプロトタイプオブジェクトを新しく作成されたオブジェクトにアタッチすることです
我々はmy_person_prototypeここではプロトタイプオブジェクトに似ています。
for(var key in my_person_prototype){
newObject[key] = my_person_prototype[key];
}
JavaScriptがプロトタイプで定義されているプロパティを実際にアタッチする方法ではありません。実際の方法は、プロトタイプチェーンのコンセプトに関連しています。
a。&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"]);
このコンストラクターの内部は、作成されたばかりのオブジェクトであるため、コンストラクターは何でも実行できます。
他のステップをシミュレートする前の最終結果:Object {name: "George"}
概要:
基本的に、関数で新しいキーワードを使用すると、そのキーワードが呼び出され、その関数はコンストラクターとして機能するため、次のように言います。
new FunctionName()
JavaScriptは、内部オブジェクト、空のハッシュを作り、ので、それは、その後、コンストラクタはそれを望んでいるものは何でもすることができ、コンストラクタにそのオブジェクトを提供します。このようコンストラクタの内部だけで作成されたオブジェクトであり、それはあなたのコースのそのオブジェクトを提供します関数でreturnステートメントを使用していない場合、またはreturn undefined;関数本体の最後にを配置した場合。
そのため、JavaScriptがオブジェクトのプロパティを検索する場合、JavaScriptが最初に行うのは、そのオブジェクトのプロパティを検索することです。そして、[[prototype]]私たちが通常持っているような秘密のプロパティがあり__proto__、そのプロパティはJavaScriptが次に見るものです。そして、それ__proto__が再び別のJavaScriptオブジェクトである限り、それ自身の__proto__属性を持ち、次__proto__をnull となるポイントに到達するまで、上から上に移動します。ポイントは、その__proto__属性がnull であるJavaScriptの唯一のオブジェクトはObject.prototypeオブジェクトです。
console.log(Object.prototype.__proto__===null);//true
これがJavaScriptで継承が機能する方法です。

言い換えると、関数にプロトタイププロパティがあり、その上で新しいプロパティを呼び出すと、JavaScriptが新しく作成されたプロパティのオブジェクトの確認を終えた後、関数のプロパティが確認され、.prototypeこのオブジェクトに独自の内部プロトタイプ。等々。