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

はじめに
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 までご連絡ください。
JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界の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の複数の顧客にサービスを提供できます

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

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

PhpStorm Mac バージョン

PhpStorm Mac バージョン

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

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境