検索
ホームページウェブフロントエンドjsチュートリアルJavaScript学習メモ(5) プロトタイプとプロトタイプチェーンの詳細解説_基礎知識

プライベート変数と関数

関数内で定義された変数と関数は、外部へのインターフェイスが提供されていない場合、つまり変数と関数が関数に対してプライベートである場合、外部からアクセスすることはできません。

コードをコピーします コードは次のとおりです:


関数テスト(){
var color = "blue";//プライベート変数
var fn = function() //プライベート関数
{

}
}

このようにして、変数 color と fn は関数オブジェクト Test の外部からアクセスできなくなり、プライベートになります:

コードをコピーします コードは次のとおりです:

var obj = new Test();
alert(obj.color);//未定義のポップアップを表示
alert(obj.fn);//上と同じ

静的変数と静的関数

関数が定義され、ドット「.」によって追加された属性と関数はオブジェクト自体からアクセスできますが、そのインスタンスにはアクセスできない場合、そのような変数と関数はそれぞれ静的変数と静的関数と呼ばれます。

コードをコピーします コードは次のとおりです:


関数 Obj(){

}
Obj.num = 72;//静的変数
Obj.fn = function() //静的関数
{

}

alert(Obj.num);//72
alert(obj.fn の種類)//function

var t = new Obj();
alert(t.name);//未定義
alert(typeof t.fn);//未定義

インスタンス変数と関数

オブジェクト指向プログラミングでは、いくつかのライブラリ関数に加えて、オブジェクトの定義時にいくつかのプロパティとメソッドを定義することが望まれます。これらはインスタンス化後にアクセスできます。

コードをコピーします コードは次のとおりです:


関数 Obj(){
This.a=[] //インスタンス変数
; This.fn=function(){ //インスタンスメソッド

}
}

console.log(obj.a の種類) //未定義
console.log(Obj.fn のタイプ); //未定義

var o=new Obj();
console.log(typeof o.a); //オブジェクト
console.log(typeof of.fn); //関数

インスタンス変数とメソッドの新しいメソッドとプロパティを追加します

コードをコピー コードは次のとおりです:


関数 Obj(){
This.a=[] //インスタンス変数
; This.fn=function(){ //インスタンスメソッド

}
}

var o1=new Obj();
o1.a.push(1);
o1.fn={};
console.log(o1.a); //[1]
console.log(o1.fn のタイプ); //オブジェクト

var o2=new Obj();
console.log(o2.a); //[]
console.log(o2.fn のタイプ); //関数

a と fn は o1 では変更されますが、o2 では変更されません。配列と関数はどちらもオブジェクトであり参照型であるため、o1 のプロパティとメソッドは o2 のものと同じ名前ですが、ただし、これは参照ではなく、Obj オブジェクトによって定義されたプロパティとメソッドのコピーです。

これは属性にとっては問題ではありませんが、メソッドにとっては大きな問題です。メソッドはまったく同じ機能を実行しますが、関数オブジェクトに 1000 のメソッドとインスタンスのメソッドがある場合、それぞれのインスタンスが 2 回コピーされるからです。何千ものメソッドのコピーを維持する必要がありますが、これは明らかに非科学的です。プロトタイプが誕生しました。

基本概念

私たちが作成するすべての関数には、オブジェクトへのポインターであるプロトタイプ属性があります。このオブジェクトの目的は、特定の型のすべてのインスタンスで共有できるプロパティとメソッドを含めることです。そして、prototypeはコンストラクタを呼び出して作成されるオブジェクトインスタンスのプロトタイプオブジェクトです。

プロトタイプを使用する利点は、オブジェクト インスタンスがそれに含まれるプロパティとメソッドを共有できることです。つまり、コンストラクターに定義オブジェクト情報を追加する代わりに、この情報をプロトタイプに直接追加できます。コンストラクターを使用する場合の主な問題は、各インスタンスで各メソッドを作成する必要があることです。

JavaScriptには、プリミティブ値とオブジェクト値の2種類の値があります。すべてのオブジェクトには、通常プロトタイプと呼ばれる内部プロパティ プロトタイプがあります。プロトタイプの値はオブジェクトまたは null にすることができます。その値がオブジェクトの場合、そのオブジェクトにも独自のプロトタイプが必要です。これにより、プロトタイプ チェーンと呼ばれる線形チェーンが形成されます。

意味

関数はコンストラクターとして使用できます。さらに、関数のみがプロトタイプ属性を持ち、アクセスできますが、オブジェクト インスタンスにはこの属性はなく、アクセスできない内部の __proto__ 属性のみが存在します。 __proto__ は、オブジェクト内の関連するプロトタイプへの暗号的なリンクです。標準によれば、__proto__ は公開されていません。つまり、プライベート プロパティですが、Firefox エンジンは、外部からアクセスして設定できるパブリック プロパティとして公開します。

コードをコピーします コードは次のとおりです:


var ブラウザ = function(){};
Browser.prototype.run = function(){
alert("私は Gecko、Firefox のカーネルです");
}

var Bro = 新しいブラウザ();
Bro.run();

Bro.run() メソッドを呼び出すと、Bro にはそのようなメソッドがないため、その __proto__ にアクセスしてそれを見つけます。これが Browser.prototype であり、最終的に run() メソッドが実行されます。 (ここでは、通常の関数と区別するため、関数の最初の文字を大文字でコンストラクタを表します)

インスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプを指す内部ポインター (__proto__) が含まれます。この接続は、インスタンスとコンストラクターのプロトタイプの間に存在します。インスタンスとコンストラクターの間には存在しません。コンストラクター。

コードをコピー コードは次のとおりです:


関数 人(名前){
This.name=name;
}

person.prototype.printName=function(){
アラート(this.name);
}

var person1=新しい人('バイロン');
var person2=新しい人('フランク');

person インスタンス person1 には name 属性が含まれており、自動的に __proto__ 属性を生成します。これは、おそらく次のようなプロトタイプで定義された printName メソッドにアクセスできます。

別の例:

コードをコピーします コードは次のとおりです:

Function Animal(name) //蓄積コンストラクター
{
This.name = name;//オブジェクトのプロパティを設定します
}
Animal.prototype.behavior = function() //基本クラスのコンストラクターのプロトタイプに動作メソッドを追加します

{
alert("これは " this.name);
}

var Dog = new Animal("dog");//Dog オブジェクトを作成します

var Cat = new Animal("cat");//猫オブジェクトを作成します

Dog.behavior();//Dog オブジェクトを通じて Behavior メソッドを直接呼び出します

Cat.behavior();//「これは猫です」を出力

alert(Dog.behavior==Cat.behavior);//出力 true;



プログラムの実行結果から、コンストラクターのプロトタイプで定義されたメソッドが実際にオブジェクトを通じて直接呼び出すことができ、コードが共有されていることがわかります。 (Animal.prototype.behavior のプロトタイプ属性を削除して、まだ機能するかどうかを確認してください。) ここで、プロトタイプ属性は Animal オブジェクトを指しています。

配列オブジェクトインスタンス

配列オブジェクトの例を見てください。オブジェクト array1 を作成するとき、JavaScript エンジンにおける array1 の実際のオブジェクト モデルは次のようになります:

コードをコピーします コードは次のとおりです:
var array1 = [1,2,3];

array1 オブジェクトの長さ属性値は 3 ですが、次のメソッドを通じて array1 に要素を追加できます:

array1.push(4); Push メソッドは、array1 の __proto__ メンバーが指すメソッド (Array.prototye.push()) から取得されます。すべての配列オブジェクト ([] によって作成されたもの) には、プッシュ、リバース、その他のメソッドで同じオブジェクト (Array.prototype) を指す __proto__ メンバーが含まれているため、これらの配列オブジェクトはプッシュ、リバース、その他のメソッドを使用できます。


関数オブジェクトインスタンス

コードをコピーします コードは次のとおりです:
function Base() {
This.id = "ベース"
}


コードをコピーします コードは次のとおりです:
var obj = 新しいBase();


このコードの結果は何ですか? Javascript エンジンで表示されるオブジェクト モデルは次のとおりです。

新しいオペレーターは具体的に何をするのですか? それは実際には非常に単純で、3 つのことを行います。

コードをコピー コードは次のとおりです:

var obj = {}; obj.__proto__ = Base.prototype
Base.call(obj);

プロトタイプチェーン

プロトタイプ チェーン: オブジェクトからプロパティまたはメソッドを呼び出すとき、オブジェクト自体にそのようなプロパティまたはメソッドがない場合、プロトタイプにプロパティまたはメソッドがない場合は、関連付けられたプロトタイプ オブジェクトに移動して探します。プロトタイプの関連付けに移動して、前のプロトタイプを検索し、それ以上ない場合は、Prototype...Prototype が未定義になるまで (オブジェクトのプロトタイプが未定義になるまで) Prototype.Prototype によって参照されるオブジェクトの検索を続けます。 )、いわゆる「プロトタイプチェーン」を形成します。

関数形状(){
This.name = "形状";
This.toString = function(){
return this.name;
}
}
関数 TwoShape(){
This.name = "2 形状";
}
関数 Triangle(辺,高さ){
This.name = "三角形";
This.side = サイド;
This.height = 高さ;
This.getArea = function(){
return this.side*this.height/2;
}
}

TwoShape.prototype = new Shape(); Triangle.prototype = new TwoShape();




ここでは、コンストラクター Shape() を使用して新しいエンティティが作成され、オブジェクトのプロトタイプをオーバーライドするために使用されます。

コードをコピーします コードは次のとおりです:
関数形状(){
This.name = "形状";
This.toString = function(){
return this.name;
}
}
関数 TwoShape(){
This.name = "2 形状";
}
関数 Triangle(辺,高さ){
This.name = "三角形";
This.side = サイド;
This.height = 高さ;
This.getArea = function(){
return this.side*this.height/2;
}
}

TwoShape.prototype = new Shape(); Triangle.prototype = new TwoShape();


TwoShape.prototype.constructor = TwoShape;

Triangle.prototype.constructor = Triangle;


var my = new Triangle(5,10);

My.getArea();

My.toString();//Triangle
My.constructor;//Triangle(side,height)



プロトタイプの継承

プロトタイプの継承: プロトタイプ チェーンの最後にあるのは、オブジェクト コンストラクターのプロトタイプ属性によって指定されるプロトタイプ オブジェクトです。このプロトタイプ オブジェクトはすべてのオブジェクトの祖先であり、すべてのオブジェクトが本質的に持つべき toString などのメソッドを実装します。 Function、Boolean、String、Date、RegExp などの他の組み込みコンストラクターのプロトタイプはすべてこの祖先から継承されていますが、それらはそれぞれ独自のプロパティとメソッドを定義しているため、子孫はそれぞれのクランの特性を示します。それらの特徴。

ECMAScript では、継承を実装する方法はプロトタイプ チェーンに依存することです。

コードをコピー コードは次のとおりです:


Function Box(){ //継承された関数はスーパータイプ(親クラス、基本クラス)と呼ばれます
This.name = "ジャック";
}

function Tree(){ //継承された関数はサブタイプ(サブクラス、派生クラス)と呼ばれます
This.age = 300;
}
//プロトタイプチェーンの継承を通じて、サブタイプのプロトタイププロパティに値を割り当てます
//new Box() はボックス構造内の情報とプロトタイプを Tree
に渡します Tree.prototype = new Box();//Tree は Box を継承し、プロトタイプを通じてチェーンを形成します

var ツリー = new Tree();
alert(tree.name);//ポップアップジャック

プロトタイプ チェーンの問題: プロトタイプ チェーンは非常に強力で、継承の実装に使用できますが、いくつかの問題もあります。そのうちの主なものは、参照型を含む値プロトタイプに由来します。参照型を含むプロトタイプ プロパティはすべてのインスタンスで共有されます。これが、プロパティがプロトタイプ オブジェクトではなくコンストラクターで定義される理由です。プロトタイプを介して継承が実装されると、プロトタイプは実際には別の型のインスタンスに戻ります。その結果、元のインスタンス プロパティがプロトタイプ プロパティになります。

サブタイプのインスタンスを作成する場合、パラメーターをスーパータイプのコンストラクターに渡すことはできません。実際、すべてのオブジェクト インスタンスに影響を与えずにスーパータイプのコンストラクターにパラメーターを渡す方法はないと言うべきです。プロトタイプに参照型の値が含まれるために今説明した問題と相まって、プロトタイプ チェーンだけが実際に使用されることはほとんどありません。

別の例:

コードをコピー コードは次のとおりです:


関数 人(名前)
{
This.name = name;//オブジェクトのプロパティを設定します
};

person.prototype.company = "Microsoft";//プロトタイプのプロパティを設定します
Person.prototype.SayHello = function() //プロトタイプメソッド
{
alert("こんにちは、" this.company の " this.name " です);
};

var BillGates = new Person("BillGates");//人物オブジェクトを作成します
BillGates.SayHello();//プロトタイプの内容を継承し、「こんにちは、Microsoft の BillGates です」を出力します

var Jobs = new Person("Jobs");
Jobs.company = "Apple";//プロトタイプの会社属性をカバーして、独自の会社属性を設定します
Jobs.SayHello = function()
{
alert("こんにちは、" this.name " like " this.company);
};
Jobs.SayHello();//属性とメソッドを自分でオーバーライドし、「Hi, Jobs like Apple」を出力します
BillGates.SayHello();//ジョブのカバレッジはプロトタイプには影響せず、BillGates は引き続き
を出力します

次のプロトタイプ チェーンの例を見てください:

コードをコピー コードは次のとおりです:


関数 Year(){
This.value = 21;
}
Year.prototype = {
メソッド:function(){

}
};

関数 Hi(){

};
//Hi のプロトタイプ属性を Year
のインスタンス オブジェクトに設定します Hi.prototype = new Year();
Hi.prototype.year = 'Hello World';

Hi.prototype.constructor = こんにちは;

var test = new Hi();//Hi の新しいインスタンスを作成します

//プロトタイプチェーン
[こんにちはインスタンス] をテストします
Hi.prototype [年のインスタンス]
{年:'Hello World'}
年.プロトタイプ
に object.prototype
                                                                                                                                                                                                          


上記の例から、テスト オブジェクトは Hi.prototype と Year.prototype を継承するため、 Year のプロトタイプ メソッド メソッドにアクセスでき、インスタンスの属性値にアクセスできます。

__ptoto__ 属性

__ptoto__ 属性 (IE ブラウザではサポートされていません) は、インスタンスからプロトタイプ オブジェクトへのポインターであり、その機能は、コンストラクターのプロトタイプ属性コンストラクターを指すことにより、属性とメソッドにアクセスできます。プロトタイプでは。

JavaScript のオブジェクト インスタンスは、基本的に一連の属性で構成されます。これらの属性の中に、内部の目に見えない特別な属性 (__proto__) があり、この属性の値はオブジェクト インスタンスのみが持つプロトタイプを指します。ユニークなプロトタイプ。

コードをコピーします コードは次のとおりです:
Function Box(){ //大文字、コンストラクター
を表す Box.prototype.name = "trigkit4";//プロトタイプ属性
Box.prototype.age = "21";
Box.prototype.run = function()//プロトタイプ メソッド
                                                                                   return this.name this.age '勉強中';
}
}

var box1 = new Box();
var box2 = new Box(); alert(box1.constructor);//構築属性、コンストラクタ自体を取得できます、

//関数はプロトタイプ ポインターによって配置され、コンストラクター自体を取得します
スクリプト>



__proto__ 属性とプロトタイプ属性の違い

プロトタイプは関数オブジェクトの独自の属性です。 __proto__ は通常のオブジェクトの暗黙的な属性です。 new を使用すると、

が指すオブジェクトを指します。 __ptoto__ は実際にはエンティティ オブジェクトの属性ですが、プロトタイプはコンストラクターに属する属性です。 __ptoto__ は学習環境またはデバッグ環境でのみ使用できます。


プロトタイプモードの実行プロセス

1. まず、コンストラクター インスタンス内の属性またはメソッドを検索し、存在する場合はすぐに返します。

2. コンストラクターのインスタンスがない場合は、そのプロトタイプ オブジェクト内でそれを探します。存在する場合は、すぐに戻ります

。 プロトタイプオブジェクトの


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール