これは非常に単純なプロトタイプベースのオブジェクトモデルであり、説明中にサンプルと見なされますが、まだコメントはありません。
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
console.log(this.name);
}
var person = new Person("George");
プロトタイプの概念を検討する前に、考慮すべき重要な点がいくつかあります。
1- JavaScript関数が実際に機能する方法:
最初のステップを実行するには、JavaScript関数が実際にどのように機能するか、this
キーワードを使用するクラスのような関数として、または引数を持つ通常の関数として、何をして何を返すかを理解する必要があります。
Person
オブジェクトモデルを作成するとします。しかし、このステップでは、キーワードを使用せずに、まったく同じことprototype
new
を実行しようとしています。
したがって、このステップ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
このオブジェクトに独自の内部プロトタイプ。等々。