JavaScriptプロトタイプの理解
20765 ワード
JavaScriptはプロトタイプベースの言語であると言われています.それで、「プロトタイプ」は重要な概念でなければなりませんか?
今日、私はプロトタイプが何であるか、あなたが知っている必要があり、プロトタイプをどのように効果的に使うかを説明します.
まず第一に、「プロトタイプ」という言葉を誤解させないでください.JavaScriptの“プロトタイプ”は英語で“プロトタイプ”と同じものではありません.それはすぐに一緒に置かれた製品の初期バージョンを意味しません.
代わりに、JavaScriptのプロトタイプは、単に何も意味しない単語です.私たちはプロトタイプをオレンジに置き換えることができます、そして、それは同じことを意味することができます.
たとえば、アップルを考えてください.アップルコンピュータが普及する前に、あなたはおそらくアップルを赤い色の果物と考えます.アップルコンピュータの「アップル」は当初意味を持ちません、しかし、それは現在それをします.
JavaScriptの場合、プロトタイプはシステムを指します.このシステムでは、オブジェクトのインスタンスを介してアクセスできるオブジェクトのプロパティを定義できます.
注:注意
プロトタイプはオブジェクト指向プログラミングと密接に関連している.どのようなオブジェクト指向プログラミングについて理解していない場合、それは意味をなさないでしょう.
私はあなたがthis introductory series on Object Oriented Programming さらに進む前に.
::
例えば、
なぜ?
これらのメソッドは、配列のプロトタイプにあります.あなたは拡張することができます
配列.プロトタイプメソッド
プロトタイプログ
両方
::
あなたが使うとき
したがって、プロトタイプの正しい定義はインスタンスがプロパティを探すときにアクセスできるオブジェクトです.
ここでは、プロパティにアクセスするときにJavaScriptがどのように動作しますか
Step 1 : JavaScriptはオブジェクト内で使用可能なプロパティをチェックします.yesの場合、JavaScriptはすぐにプロパティを使用します.
ステップ2 :プロパティがオブジェクトの内部でない場合、JavaScriptはプロトタイプが利用可能かどうかをチェックします.プロトタイプがあれば、ステップ1を繰り返してください(そして、プロパティがプロトタイプの中にあるかどうかチェックしてください).
ステップ3 :プロトタイプが残っていない場合、JavaScriptはプロパティを見つけることができません. リターン エラーをスローします(メソッドを呼び出した場合). 概略的に、次のようになります.
我々にはあると言いましょう
ここにコードがあります
ここでどのように書くだろう
ここにコードがあります
プロトタイプの委任と原型継承は同じことを意味します.
彼らは単にプロトタイプシステムを使うと言います
JavaScriptはプロトタイプベースの言語であるため、プロトタイプ型のデリゲートを使用する必要があります.正しい?
ではなく.
私は、あなたがオブジェクト指向プログラミングを書く方法に依存すると主張します.より便利であるので、あなたがクラスを使うならば、それはプロトタイプを使うことを意味します.
あなたのアプリが何百万もの操作を必要としない限り、2つの方法の間のパフォーマンスは重要でありません.このセクションでは、この点を証明するためにいくつかの実験を共有します.
私たちは
その後、タイムスタンプの違いを取得し、どのくらいの操作がかかったかを測定します.
まず最初に、私はそれがプロトタイプ自身を通してメソッドにアクセスするのにどれくらいかかるかをテストしました.
以下はコードです.
テスト
10万のops
1000万ops
オブジェクト
3 ms
15 ms
プロトタイプ
2 ms
12 ms
注:結果はFirefoxのdevtoolsからです.読めるthis 私がなぜFirefoxでベンチマークであるかについて理解するために.
評決:プロトタイプを使用するかどうかは問題ではない.100万の操作を実行しない限り、違いは生じません.
私がこのテストを実行しなければならなかったのは、クラスを使用するときにプロトタイプを使うことを推奨し、ファクトリ関数を使用するときにプロトタイプを使用しないことです.
私は、ファクトリ関数を作成するかどうかをクラスを作成するよりもかなり遅くテストする必要がありました.
これがコードです.
テスト
10万のops
1000万ops
クラス
5 ms
18 ms
ファクトリー
6 ms
18 ms
評決:クラスまたはファクトリ関数を使用するかどうかは問題ではありません.100万稼動をしても違いはない.
クラスまたはファクトリ関数を使用できます.あなたはプロトタイプを使用するかを選択することができますを選択します.それは本当にあなた次第です.
パフォーマンスを心配する必要はありません.
読書ありがとう.この記事はもともと投稿されたmy blog . サインアップするmy newsletter あなたがより良いフロントエンド開発者になるために、より多くの記事が欲しいならば.
今日、私はプロトタイプが何であるか、あなたが知っている必要があり、プロトタイプをどのように効果的に使うかを説明します.
プロトタイプとは
まず第一に、「プロトタイプ」という言葉を誤解させないでください.JavaScriptの“プロトタイプ”は英語で“プロトタイプ”と同じものではありません.それはすぐに一緒に置かれた製品の初期バージョンを意味しません.
代わりに、JavaScriptのプロトタイプは、単に何も意味しない単語です.私たちはプロトタイプをオレンジに置き換えることができます、そして、それは同じことを意味することができます.
たとえば、アップルを考えてください.アップルコンピュータが普及する前に、あなたはおそらくアップルを赤い色の果物と考えます.アップルコンピュータの「アップル」は当初意味を持ちません、しかし、それは現在それをします.
JavaScriptの場合、プロトタイプはシステムを指します.このシステムでは、オブジェクトのインスタンスを介してアクセスできるオブジェクトのプロパティを定義できます.
注:注意
プロトタイプはオブジェクト指向プログラミングと密接に関連している.どのようなオブジェクト指向プログラミングについて理解していない場合、それは意味をなさないでしょう.
私はあなたがthis introductory series on Object Oriented Programming さらに進む前に.
::
例えば、
Array
配列インスタンスの青写真です.配列のインスタンスを作成する[]
or new Array()
.const array = ['one', 'two', 'three']
console.log(array)
// Same result as above
const array = new Array('one', 'two', 'three')
あなたならばconsole.log
この配列では、メソッドはありません.しかし、あなたはconcat
, slice
, filter
, and map
!なぜ?
これらのメソッドは、配列のプロトタイプにあります.あなたは拡張することができます
__proto__
オブジェクト(クロムdevtools )あるいは<prototype>
オブジェクト(Firefoxのdevtools)とメソッドのリストが表示されます.配列.プロトタイプメソッド
プロトタイプログ
prototype
注:注意両方
__proto__
クロムと<prototype>
Firefoxはプロトタイプオブジェクトを指します.それらは異なるブラウザーで異なって書かれます.::
あなたが使うとき
map
, ジャバスクリプトmap
オブジェクト自体.If map
が見つからない場合、JavaScriptはプロトタイプを探します.JavaScriptがプロトタイプを見つけた場合、それはmap
そのプロトタイプで.したがって、プロトタイプの正しい定義はインスタンスがプロパティを探すときにアクセスできるオブジェクトです.
プロトタイプチェーン
ここでは、プロパティにアクセスするときにJavaScriptがどのように動作しますか
Step 1 : JavaScriptはオブジェクト内で使用可能なプロパティをチェックします.yesの場合、JavaScriptはすぐにプロパティを使用します.
ステップ2 :プロパティがオブジェクトの内部でない場合、JavaScriptはプロトタイプが利用可能かどうかをチェックします.プロトタイプがあれば、ステップ1を繰り返してください(そして、プロパティがプロトタイプの中にあるかどうかチェックしてください).
ステップ3 :プロトタイプが残っていない場合、JavaScriptはプロパティを見つけることができません.
undefined
(プロパティにアクセスしようとした場合).プロトタイプチェーンの例
我々にはあると言いましょう
Human
クラス.また、私たちはDeveloper
継承するサブクラスHuman
. Human
sがあるsayHello
メソッドとDevelopers
を持っているcode
メソッド.ここにコードがあります
Human
class Human {
constructor(firstName, lastName) {
this.firstName = firstName
this.lastname = lastName
}
sayHello () {
console.log(`Hi, I'm ${this.firstName}`)
}
}
注:注意Human
とDeveloper
以下はコンストラクタ関数で記述できます.コンストラクタ関数を使用する場合prototype
より明確になりますが、サブクラスの作成は難しくなります.だから私はクラスの例を示している.(参照)this article オブジェクト指向プログラミングを使用する4つの異なる方法のために.ここでどのように書くだろう
Human
代わりにコンストラクタを使用する場合.function Human (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
Human.prototype.sayHello = function () {
console.log(`Hi, I'm ${this.firstName}`)
}
::ここにコードがあります
Developer
.class Developer extends Human {
code (thing) {
console.log(`${this.firstName} coded ${thing}`)
}
}
エーDeveloper
インスタンスはcode
and sayHello
これらのメソッドはインスタンスのプロトタイプチェーンにあります.const zell = new Developer('Zell', 'Liew')
zell.sayHello() // Hi, I'm Zell
zell.code('website') // Zell coded website
あなたならばconsole.log
インスタンスは、プロトタイプのチェーンでメソッドを見ることができます.プロトタイプ型委任/原型継承
プロトタイプの委任と原型継承は同じことを意味します.
彼らは単にプロトタイプシステムを使うと言います
prototype
オブジェクト.プロトタイプの代表団を使うべきですか?
JavaScriptはプロトタイプベースの言語であるため、プロトタイプ型のデリゲートを使用する必要があります.正しい?
ではなく.
私は、あなたがオブジェクト指向プログラミングを書く方法に依存すると主張します.より便利であるので、あなたがクラスを使うならば、それはプロトタイプを使うことを意味します.
class Blueprint {
method1 () {/* ... */}
method2 () {/* ... */}
method3 () {/* ... */}
}
しかし、ファクトリ関数を使用する場合、プロトタイプを使用しないという意味です.function Blueprint {
return {
method1 () {/* ... */}
method2 () {/* ... */}
method3 () {/* ... */}
}
}
再び、読み取りthis article オブジェクト指向プログラミングを書く4つの異なった方法のために.性能含意
あなたのアプリが何百万もの操作を必要としない限り、2つの方法の間のパフォーマンスは重要でありません.このセクションでは、この点を証明するためにいくつかの実験を共有します.
セットアップ
私たちは
performance.now
任意の操作を実行する前にタイムスタンプをログ出力します.操作を実行した後、我々は使用されますperformance.now
タイムスタンプを再度ログ出力します.その後、タイムスタンプの違いを取得し、どのくらいの操作がかかったかを測定します.
const start = performance.now()
// Do stuff
const end = performance.now()
const elapsed = end - start
console.log(elapsed)
私はperf
私のテストを支援する関数function perf (message, callback, loops = 1) {
const startTime = performance.now()
for (let index = 0; index <= loops; index++) {
callback()
}
const elapsed = performance.now() - startTime
console.log(message + ':', elapsed)
}
注:あなたはもっと学ぶことができますperformance.now
インthis article .試作実験1プロトタイプを用いないプロトタイプの使用
まず最初に、私はそれがプロトタイプ自身を通してメソッドにアクセスするのにどれくらいかかるかをテストしました.
以下はコードです.
class Blueprint () {
constructor () {
this.inObject = function () { return 1 + 1 }
}
inPrototype () { return 1 + 1 }
}
const count = 1000000
const instance = new Blueprint()
perf('In Object', _ => { instance.inObject() }, count)
perf('In Prototype', _ => { instance.inPrototype() }, count)
この結果は以下の通りである.テスト
10万のops
1000万ops
オブジェクト
3 ms
15 ms
プロトタイプ
2 ms
12 ms
注:結果はFirefoxのdevtoolsからです.読めるthis 私がなぜFirefoxでベンチマークであるかについて理解するために.
評決:プロトタイプを使用するかどうかは問題ではない.100万の操作を実行しない限り、違いは生じません.
実験対2:クラス対工場機能
私がこのテストを実行しなければならなかったのは、クラスを使用するときにプロトタイプを使うことを推奨し、ファクトリ関数を使用するときにプロトタイプを使用しないことです.
私は、ファクトリ関数を作成するかどうかをクラスを作成するよりもかなり遅くテストする必要がありました.
これがコードです.
// Class blueprint
class HumanClass {
constructor (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
sayHello () {
console.lg(`Hi, I'm ${this.firstName}}`)
}
}
// Factory blueprint
function HumanFactory (firstName, lastName) {
return {
firstName,
lastName,
sayHello () {
console.log(`Hi, I'm ${this.firstName}}`)
}
}
}
// Tests
const count = 1000000
perf('Class', _ => { new HumanClass('Zell', 'Liew') }, count)
perf('Factory', _ => { HumanFactory('Zell', 'Liew') }, count)
平均結果を次の表にまとめます.テスト
10万のops
1000万ops
クラス
5 ms
18 ms
ファクトリー
6 ms
18 ms
評決:クラスまたはファクトリ関数を使用するかどうかは問題ではありません.100万稼動をしても違いはない.
性能試験終了
クラスまたはファクトリ関数を使用できます.あなたはプロトタイプを使用するかを選択することができますを選択します.それは本当にあなた次第です.
パフォーマンスを心配する必要はありません.
読書ありがとう.この記事はもともと投稿されたmy blog . サインアップするmy newsletter あなたがより良いフロントエンド開発者になるために、より多くの記事が欲しいならば.
Reference
この問題について(JavaScriptプロトタイプの理解), 我々は、より多くの情報をここで見つけました https://dev.to/zellwk/understanding-javascript-prototype-5187テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol