ホームページ ウェブフロントエンド jsチュートリアル JavaScriptシリーズを深く理解する (6) 強力なプロトタイプとプロトタイプchain_javascriptスキル

JavaScriptシリーズを深く理解する (6) 強力なプロトタイプとプロトタイプchain_javascriptスキル

May 16, 2016 pm 05:57 PM
プロトタイプ プロトタイプチェーン

はじめに
JavaScript には従来のクラス継承モデルは含まれていませんが、プロトタイプのプロトタイプ モデルが使用されています。

これは JavaScript の欠点としてよく指摘されますが、プロトタイプベースの継承モデルは実際には従来のクラス継承よりも強力です。従来のクラス継承モデルの実装は簡単ですが、JavaScript でのプロトタイプ継承の実装ははるかに困難です。

JavaScript はプロトタイプ継承に基づいて広く使用されている唯一の言語であるため、2 つの継承モデルの違いを理解するには時間がかかります。今日はプロトタイプとプロトタイプ チェーンについて学びます。

プロトタイプ
10 年前、初めて JavaScript を学んだとき、私は通常次の方法でコードを書きました:

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

var decmalDigits = 2,
tax = 5;

function add(x, y) {
return x y ;
}

関数subtract(x, y) {
return x - y>}

//alert(add(1, 3));

各関数を実行して結果を取得します。プロトタイプを学習した後、次のメソッドを使用してコードを美しくすることができます。

プロトタイプの使用方法 1:
プロトタイプを使用する前に、コードに小さな変更を加える必要があります:

コードをコピー コードは次のとおりです。
var Calculator = function (decimalDigits, 税) {
this.decmalDigits = decmalDigits;
>};


次に、Calculator オブジェクトのプロトタイプ プロパティにオブジェクト リテラルを代入して、Calculator オブジェクトのプロトタイプを設定します。


Calculator.prototype = {
add : function (x, y) {
return x y;
},

subtract: function (x, y) {
return x - y; ;
//alert((new Calculator()).add(1, 3));


このようにして、新しい Calculator オブジェクトの後に add メソッドを呼び出して結果を計算できます。 。

プロトタイプの使用方法 2:
2 つ目の方法は、プロトタイプのプロトタイプを割り当てるときに関数がすぐに実行される式を使用する方法です。これは次の形式です。

Calculator.prototype = function () { } ();
その利点は、前の投稿ですでに知られています。つまり、プライベート関数をカプセル化し、単純な使用名を return の形式で公開して、パブリック/プライベート効果を実現できます。




コードをコピー
コードは次のとおりです: Calculator.prototype = function () { add = function (x, y) {
return x y;
},

subtract = function (x, y) {
return x - y
}
return {
add: 加算、
subtract: 減算
}
} ();

//alert((new Calculator()).add (11 , 3));


同様に、新しい Calculator オブジェクトを作成し、後で add メソッドを呼び出して結果を計算できます。

もう 1 つのポイント
ステップバイステップのステートメント:
上記のプロトタイプを使用する場合、プロトタイプ オブジェクトを一度に設定するという制限があります。各属性を設定する方法について説明します。プロトタイプは別途。




コードをコピー
コードは次のとおりです。 var BaseCalculator = function () { // 各インスタンスの 10 進数を宣言します
this.decmalDigits = 2;
}

// プロトタイプを使用して BaseCalculator の 2 つのオブジェクト メソッドを拡張します
BaseCalculator.prototype.add = 関数 (x, y) {
戻り x y;
};

BaseCalculator.prototype.subtract = 関数 (x, y) {
戻り x - y; ;


まず、コンストラクターで BaseCalculator オブジェクトを宣言し、10 進数属性 decmalDigits を初期化してから、プロトタイプ属性を通じて add(x,y) とsubtract という 2 つの関数を設定します。 ( x, y)、もちろん、上記の 2 つのメソッドのいずれかを使用することもできます。私たちの主な目的は、BaseCalculator オブジェクトを実際の Calculator のプロトタイプに設定する方法を確認することです。



コードをコピー
コードは次のとおりです。 var BaseCalculator = function() { this. 10 進数 = 2;
BaseCalculator.prototype = {
add: function(x, y) {
return x y>},
subtract : function(x, y) {
return x - y>}
};
上記のコードを作成したら、開始しましょう:
コードをコピーします コードは次のとおりです:

var Calculator = function () {
//各インスタンスの税番号を宣言します
this.tax = 5;
Calculator.prototype = new BaseCalculator( ) ;


Calculator が 2 つの関数 add(x,y) とsubtract(x,y) を統合できるようにするために、Calculator のプロトタイプが BaseCalculator のインスタンスを指していることがわかります。そしてもう 1 つ言っておきたいのは、そのプロトタイプは BaseCalculator のインスタンスであるため、作成した Calculator オブジェクトのインスタンスの数に関係なく、それらのプロトタイプは同じインスタンスを指すということです。


コードをコピーします コードは次のとおりです。
var calc = new Calculator(); 🎜>alert (calc.add(1, 1));
//BaseCalculator で宣言された 10 進数属性は、電卓でアクセスできます。上記のコードを実行すると、Calculator のプロトタイプが BaseCalculator のインスタンスを指しているため、BaseCalculator のコンストラクターで宣言された属性値に Calculator がアクセスしたくない場合は、その DecimalDigits 属性値にアクセスできることがわかります。するの?これを実行します:




コードをコピーします


コードは次のとおりです:
var Calculator = function ( ) { this.tax= 5; }; Calculator.prototype = BaseCalculator.prototype;

Calculator のプロトタイプに代入する次のコードにアクセスすると、インスタンスで 10 進数の値にアクセスできません。エラーが発生します。




コードをコピーします


コードは次のとおりです。
var calc = new Calculator(); 🎜>alert (calc.add(1, 1)); alert(calc.decmalDigits); サードパーティの JS ライブラリを使用する場合、彼らが定義したプロトタイプ メソッドは私たちのニーズを満たすことはできませんが、これらはこのクラス ライブラリから分離できないため、現時点ではプロトタイプ内の 1 つ以上のプロパティまたは関数を書き直す必要があります。同じものを宣言し続けることができます。追加コードの形式は次のとおりです。前の追加関数を上書きして書き換えます。 コードは次のとおりです。



コードをコピーします。

コードは次のとおりです。

//前の電卓の add() 関数をオーバーライドします。
Calculator.prototype.add = function (x, y) { return x y this.tax; var calc = new Calculator(); alert(calc.add(1, 1));
このようにして、計算結果には元の税金より 1 つ多くの税金が含まれます。値は 1 つですが、注意すべき点が 1 つあります。書き換えられたコードは、前のコードを上書きできるように最後に配置する必要があります。

プロトタイプ チェーン
プロトタイプをチェーンする前に、最初に次のコードを追加します。




コードをコピー

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


function Foo() {
this.value = 42;
} Foo.prototype = { method: function() {} }; function Bar() {}
// Bar のプロトタイプ属性を Foo のインスタンス オブジェクトに設定します
Bar.prototype = new Foo(); >Bar.prototype .foo = 'Hello World';

// Bar.prototype.constructor を Bar 自体に修正します
Bar.prototype.constructor = Bar test = new Bar() // Bar の新しいインスタンスを作成します

// プロトタイプ チェーン
test [Bar のインスタンス]
Bar.prototype [Foo のインスタンス]
{ foo: 'Hello World ' }
Foo.prototype
{メソッド: ...};
Object.prototype
{toString: ... /* など */};
上記の例では、テスト オブジェクトは Bar.prototype と Foo.prototype を継承しているため、Foo のプロトタイプ メソッドにアクセスできます。同時に、プロトタイプで定義された Foo インスタンスのプロパティ値にもアクセスできます。 new Bar() は新しい Foo インスタンスを作成するのではなく、そのプロトタイプ上のインスタンスを再利用するため、すべての Bar インスタンスは同じ value プロパティを共有することに注意してください。

プロパティ検索:
オブジェクトのプロパティを探すとき、JavaScript は指定された名前のプロパティが見つかるまで、検索がプロトタイプ チェーンの先頭に到達するまで、プロトタイプ チェーンを上方向に走査します。は、Object.prototype - ただし、指定された属性がまだ見つからない場合は、unknown が返されます。例を見てみましょう:
コードをコピー コードは次のとおりです。

function foo() {
this.add = function (x, y) {
return x y;
}

foo.prototype.add = function (x, y) {
return x y 10;
}

Object.prototype.subtract = function (x, y) {
return x - y;
}

var f = new foo();
alert(f.add(1, 2)); // 結果は 13 ではなく 3 です。
alert(f.subtract(1, 2)); //結果は -1

コードを実行すると、結果を取得するために、いわゆる上向き検索がインストールされることがわかります。 、ただし、追加方法は少し異なります。私が強調しているのは、属性を検索するときに、最初に自分の属性を検索し、プロトタイプがない場合は、プロトタイプを検索するということです。次に、それを Object のプロトタイプに挿入します。そのため、特定のレベルでは、for in ステートメントを使用してプロパティを走査する場合、効率も問題になります。

もう 1 つ注意する必要があるのは、プロトタイプには任意のタイプのオブジェクトを割り当てることができますが、アトミック タイプの値を割り当てることはできないということです。たとえば、次のコードは無効です。 >

コードをコピーします
コードは次のとおりです。 function Foo() {} Foo.prototype = 1;無効な

hasOwnProperty 関数:
hasOwnProperty は Object.prototype のメソッドです。hasOwnProperty があるため、オブジェクトにプロトタイプ チェーンのプロパティの代わりにカスタム プロパティが含まれているかどうかを判断できます。プロトタイプチェーンを検索せずにプロパティを処理する唯一の関数です。



コードをコピー
コードは次のとおりです: // Object.prototype を変更 Object.prototype .bar = 1;
var foo = {goo: unknown};

foo.bar; // 1
'bar' // true

foo.hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true


オブジェクトを走査するときに正しい結果を与えることができるのは hasOwnProperty だけですプロパティが役立つ場合があります。 プロトタイプ チェーン上のプロパティを除外するには、オブジェクト自体に定義されたプロパティ以外に方法はありません。

しかし、嫌なことがあります。JavaScript は hasOwnProperty が不法に占有されることを保護しないため、オブジェクトがたまたまこのプロパティを持っている場合、正しい結果を得るには外部の hasOwnProperty 関数を使用する必要があります。




コードをコピー
コードは次のとおりです: var foo = { hasOwnProperty: function() {
return false;
bar: 'Here be Dragons'
} // 常に false を返します。

// {} オブジェクトの hasOwnProperty を使用し、その上部と下部を foo に設定します
{}.hasOwnProperty.call(foo, 'bar') // true

;
hasOwnProperty は、オブジェクトにプロパティが存在するかどうかを確認するときに使用できる唯一のメソッドです。同時に、for in ループを使用してオブジェクトを走査する場合は、常に hasOwnProperty メソッドを使用することをお勧めします。これにより、プロトタイプ オブジェクトの展開による干渉が回避されます。



コードをコピーします

コードは次のとおりです:
// Object.prototype を変更 Object.prototype.bar = 1 ; var foo = { moo: 2}; for(var i in foo) { console.log(i); // 2 つの属性を出力します: bar と moo
}


us for in ステートメントの動作を変更する方法はないため、結果をフィルターしたい場合は、hasOwnProperty メソッドのみを使用できます。コードは次のとおりです。



コードをコピー

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

// foo 変数は上記の例の変数です。
for(var i in foo) {
if (foo.hasOwnProperty(i)) {
console.log(i) );
}
}

このバージョンのコードが唯一の正しい書き方です。 hasOwnPropertyを使用したので、今回はmooのみが出力されます。 hasOwnProperty が使用されていない場合、ネイティブ オブジェクト プロトタイプ (Object.prototype など) が拡張されるときにこのコードが壊れる可能性があります。

要約: hasOwnProperty を使用し、コードが実行される環境についていかなる仮定も立てず、ネイティブ オブジェクトが拡張されているかどうかも仮定しないことをお勧めします。

まとめ
プロトタイプによって開発コードは大幅に充実しましたが、日常の使用では上記の注意事項のいくつかに注意する必要があります。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

原神バージョン 4.4 の新しいマップの紹介 原神バージョン 4.4 の新しいマップの紹介 Jan 31, 2024 pm 06:36 PM

原神 バージョン 4.4 の新しいマップの紹介. 皆さん、原神 4.4 バージョンでは、立月のシー ランタン フェスティバルも始まりました. 同時に、バージョン 4.4 では神羽渓谷と呼ばれる新しいマップ エリアが開始されます。提供された情報によると、沈雨谷は実際には喬営村の一部ですが、プレイヤーはそれを沈雨谷と呼ぶことに慣れています。それでは、新しい地図をご紹介します。原神バージョン 4.4 の新マップのご紹介です。バージョン 4.4 では、立月北部に「陳兪渓谷・上谷」、「陳兪渓谷・南嶺」、「来新山」がオープンします。谷・上谷」。 ※魔神クエスト・第3幕「ドラゴンと自由の歌」プロローグをクリアすると、テレポートアンカーポイントが自動で解放されます。 2. 喬営荘 暖かい春風が再び陳嶼の山野を撫でるとき、香りのよい

スコープチェーンとプロトタイプチェーンとは何ですか? スコープチェーンとプロトタイプチェーンとは何ですか? Nov 13, 2023 pm 01:46 PM

スコープ チェーンとプロトタイプ チェーンは、JavaScript の 2 つの重要な概念であり、それぞれスコープと継承の 2 つの中核機能に対応します: 1. スコープ チェーンは、JavaScript で変数アクセスとスコープを管理するために使用されるメカニズムです。関数が作成される実行コンテキストと字句スコープ; 2. プロトタイプ チェーンは、JavaScript で継承を実装するためのメカニズムです。オブジェクト間のプロトタイプ関係に基づいて、オブジェクトのプロパティやメソッドにアクセスするとき、オブジェクト自体がそうでない場合は、定義は、プロトタイプ チェーンに沿って検索されます。

プロトタイプとプロトタイプチェーンとは何ですか プロトタイプとプロトタイプチェーンとは何ですか Nov 09, 2023 pm 05:59 PM

js のオブジェクトであるプロトタイプは、他のオブジェクトのプロパティとメソッドを定義するために使用されます。各コンストラクターには、プロトタイプ属性があります。この属性は、プロトタイプ オブジェクトを指すポインターです。新しいオブジェクトが作成されると、新しいオブジェクトは次のようになります。コンストラクターのprototype属性はプロパティとメソッドを継承します。プロトタイプ チェーンでは、オブジェクトのプロパティにアクセスしようとすると、js はまずオブジェクトにこのプロパティがあるかどうかを確認します。そうでない場合、js はオブジェクトのプロトタイプを参照します。プロトタイプ オブジェクトにこのプロパティがない場合は、原型の原型を探し続ける。

Go 言語と Python のパフォーマンス比較: 高パフォーマンス プログラミングに適しているのはどちらですか? Go 言語と Python のパフォーマンス比較: 高パフォーマンス プログラミングに適しているのはどちらですか? Jan 30, 2024 am 08:13 AM

Go 言語と Python は非常に人気のある 2 つのプログラミング言語であり、それぞれに独自の利点と特徴があります。高性能プログラミングに関しても、この 2 つにはいくつかの違いがあります。この記事では、Go 言語と Python を比較して、どちらが高パフォーマンス プログラミングに適しているかを検討します。まず、Go 言語について理解しましょう。 Go 言語は、シンプルさ、効率性、同時実行性に重点を置いて Google によって開発されたオープンソース プログラミング言語です。 Go 言語の設計目標の 1 つは、高パフォーマンスのプログラミング エクスペリエンスを提供することです。軽量のコルーチンがあります (Goro

プロトタイプとプロトタイプチェーンの違いは何ですか プロトタイプとプロトタイプチェーンの違いは何ですか Nov 09, 2023 pm 04:48 PM

プロトタイプとプロトタイプ チェーンの違いは次のとおりです。 1. プロトタイプは、オブジェクト間での属性とメソッドの共有と継承を実現するために使用される、いくつかの共有属性とメソッドを含む各オブジェクトが持つ属性です。一方、プロトタイプ チェーンは継承です。このメカニズムは、オブジェクト間の継承関係を定義するオブジェクト間のプロトタイプ関係を通じて実装され、オブジェクトがプロトタイプ オブジェクトのプロパティとメソッドを共有できるようになります。 2. プロトタイプの機能は、オブジェクトの共有プロパティとメソッドを定義することです。複数のオブジェクトが同じプロトタイプ オブジェクトのプロパティとメソッドを共有できるようにするため、プロトタイプ チェーンの機能はオブジェクト間の継承関係などを実現することです。

適切なプログラミング言語を選択する: Go と Python を比較して、プロジェクトのニーズに最適な選択を決定します 適切なプログラミング言語を選択する: Go と Python を比較して、プロジェクトのニーズに最適な選択を決定します Jan 30, 2024 am 08:00 AM

今日の急速な技術進歩の時代では、プログラミング言語の選択は非常に重要になっています。ソフトウェア開発分野の継続的な発展に伴い、Go言語とPythonは非常に注目を集めている2つのプログラミング言語となっています。この記事では、読者がプロジェクトのニーズに応じて適切なプログラミング言語を選択できるように、Go 言語と Python の比較分析を行います。まず、Go 言語について理解しましょう。 Go 言語は、Google によって開発された静的にコンパイルされたプログラミング言語です。強力な同時処理機能と効率的なガベージ コレクション メカニズムを備えています。

国産の無料プログラミングツールが人気!清華大学の博士チームによって開発され、応答遅延が短く、精度が高いです。 国産の無料プログラミングツールが人気!清華大学の博士チームによって開発され、応答遅延が短く、精度が高いです。 Jan 31, 2024 pm 05:03 PM

昨年、大規模モデル テクノロジーの広範な適用により、私たちは AI が私たちの働き方をいかに大きく変えたかを目の当たりにしてきました。プログラミングの分野でもAIの介入はプログラマーにこれまでにない利便性をもたらすでしょう。最近、Feishen Technology は、大規模な自社開発コード モデルに基づく AI コード アシスタント FittenCode をリリースしました。これにより、プログラマーはコーディング タスクをより迅速、正確、高品質で完了できるようになり、コーディング効率が大幅に向上し、無料でオープンなサービスに貢献できます。ユーザー!製品の公式 Web サイトのアドレス: https://code.fittentech.com/FittenCode は、前回のリリース以来すぐに人気になりました。開発チームは機能を提供するために 24 時間体制で取り組みました。

JSプロトタイプとプロトタイプチェーンの役割は何ですか JSプロトタイプとプロトタイプチェーンの役割は何ですか Nov 09, 2023 pm 04:56 PM

js プロトタイプとプロトタイプ チェーンの機能は、オブジェクトの継承を実現し、メモリ領域を節約し、コードのパフォーマンスと保守性を向上させることです。詳細な導入: 1. オブジェクトの継承を実装します。プロトタイプとプロトタイプ チェーンを使用すると、オブジェクトを作成し、別のオブジェクトのプロパティとメソッドを継承できます。新しいオブジェクトを作成するときに、そのプロトタイプを別のオブジェクトにポイントできるため、新しいオブジェクト オブジェクトは、プロトタイプ オブジェクトのプロパティとメソッドにアクセスできます; 2. メモリを節約し、パフォーマンスを向上させます。JavaScript では、各オブジェクトにプロトタイプがあります。プロトタイプ チェーンを通じて、オブジェクトはプロトタイプなどを共有できます。

See all articles