ほとんどのプログラミング言語では、クラスとオブジェクトがあり、1つのクラスが他のクラスを継承できます。
JavaScriptでは、継承はプロトタイプベースです。つまり、JavaScriptにはクラスがなく、代わりにあるオブジェクトが別のオブジェクトを継承します。 :)
1。継承、原子
JavaScriptでは、オブジェクトウサギが別のオブジェクト動物を継承する場合、ウサギオブジェクトに特別な特性があることを意味します。
ウサギオブジェクトにアクセスするとき、通訳者がウサギのプロパティを見つけることができない場合、__Proto__チェーンに従って動物オブジェクトで検索します
Chestnutsの__Proto__属性は、ChromeとFirefoxでのみアクセスできます。栗をご覧ください:
var animal = {eats:true} var rabbit = {jumps:true} rabbit .__ proto__ = animal // enternitert(rabbit.eats)// trueEats属性は動物のオブジェクトからアクセスされます。
属性がRabbitオブジェクトで見つかった場合、Proto属性はチェックされません。
別の栗を持ちましょう。サブクラスにEats属性もある場合、親クラスにはアクセスされません。
var animal = {eats:true} var feduprabbit = {eats:false} feduprabbit .__ proto__ = animal alert(feduprabbit.eats)// false動物に機能を追加することもできます。また、ウサギでアクセスすることもできます。
var animal = {eat:function(){alert( "im full")this.full = true}} var rabbit = {jump:function(){ / * monthy * /}} rabbit .__ proto__ = animal(1)rabbit.eat():
rabbit.eat()関数は、次の2つのステップで実行されます。
まず、通訳者はrabbit.eatを探します。ウサギには食事機能はないので、ウサギ.__ Proto__に沿って見上げて動物で見つけました。
関数はこれで実行されます=ウサギ。この値は、__Proto__属性とは何の関係もありません。
したがって、this.full = true in rabbit:
ここで私たちが行った新しい発見を見てみましょう。オブジェクトは親関数を呼び出しますが、これはまだオブジェクト自体、つまり継承です。
__Proto__が参照するオブジェクトはプロトタイプと呼ばれ、動物はウサギのプロトタイプです(翻訳者の注:これはウサギの__Proto__属性です。
(2)書くときではなく、読むときは検索します
this.propなどのオブジェクトを読み取るとき、インタープリターはそのプロトタイプのプロパティを探します。
this.prop = valueなどの属性値を設定する場合、検索する理由はありません。この属性(prop)がこのオブジェクトに直接追加されます(これはこれです)。 delete obj.propは類似しており、オブジェクト自体のプロパティのみを削除し、プロトタイプのプロパティはそのままです。
(3)Protoについて
ガイドを読んでいる場合は、ここではガイドにある__proto__を[[プロトタイプ]]と呼んでいます。プロトタイプと呼ばれる別のプロパティがあるため、両方のブラケットが重要です。
2。object.create、object.getPrototypeof
__Proto__は、Chrome/Firefoxによって提供される非標準のプロパティであり、他のブラウザでは見えないままです。
Operaを除くすべての最新のブラウザ(IE> 9)は、プロトタイプの問題を処理するための2つの標準関数をサポートしています。
object.ceate(prop、props])
指定されたプロトで空のオブジェクトを作成します:
var animal = {eats:true} rabbit = object.create(animal)alert(rabbit.eats)// true上記のコードは空のウサギオブジェクトを作成し、プロトタイプは動物に設定されます
ウサギオブジェクトが作成された後、プロパティを追加できます。
var animal = {eats:true} rabbit = object.create(animal)rabbit.jumps = trueObject.Creat関数の2番目のパラメーターはオプションであり、プロパティを新しいオブジェクトのように設定できます。これは、私たちの関係の相続のために省略されています。
(1)object.getPrototypeof(obj)
obj .__ proto__の値を返します。この関数は標準であり、__Proto__属性に直接アクセスできないブラウザで使用できます。
var animal = {eats:true} rabbit = object.create(animal)alert(object.getPrototypeof(rabbit)===== [動物)// true最新のブラウザでは、__Proto__属性値を読み取ることができますが、設定することはできません。
3。プロトタイプ
コンストラクター関数を使用する__Proto__属性を設定するためのいくつかの優れたクロスブラウザーの方法があります。覚えて!任意の関数は、新しいキーワードを介してオブジェクトを作成します。
栗:
function rabbit(name){this.name = name} var rabbit = new Rabbit( 'john')alert(rabbit.name)// john新しい操作は、プロトタイプのプロパティを、ウサギオブジェクトの__Proto__プロパティに設定します。
動物を継承する新しいウサギオブジェクトなどの原則を見てみましょう。
var animal = {eats:true} function rabbit(name){this.name = name} rabbit.prototype = animalvar rabbit = new rabbit( 'john')alert(rabbit.eats)// true、rabbit .__ proto__ ==動物rabbit.prototype =動物リテラル手段:set __proto__ =新しいウサギによって作成されたすべてのオブジェクトの動物
4。Cross-Browser object.create(proto)
Object.create(prop)関数は、特定のオブジェクトからの直接的な継承を可能にするため、強力です。次のコードでシミュレートできます。
function Enersit(proto){function f(){} f.prototype = proto return new f}継承(動物)はobject.create(動物)とまったく同じです。
栗:
var animal = {eats:true} var rabbit = ensulit(animal)alert(rabbit.eats)// truealert(rabbit.hasownproperty( 'eats'))// false、プロトタイプからその原則が何であるかを見てみましょう。
function enternit(proto){function f(){} //(1)f.prototype = proto //(2)return new f()//(3)}(1)新しい関数が作成され、関数はこれに属性を設定しなかったため、「新しいf」は空のオブジェクトを作成します。
(2) `f.prototype`はprotoに設定されています
(3) `new` f空のオブジェクトを作成します。オブジェクトの` __proto__ = f.prototype`
(4)ビンゴ! 「proto」を継承する空のオブジェクトを取得します
この関数は、さまざまなライブラリとフレームワークで広く使用されています。
あなたの関数はオプションを備えたオブジェクトを受け入れます
/ *オプションにはメニューの設定が含まれています:幅、高さなどを含む */functionメニュー(オプション){// ...}特定のオプション機能メニュー(オプション){options.width = options.width ||を設定する必要があります。 300 //デフォルト値を設定// ...}。 。 。ただし、パラメーター値を変更すると、外部コードでオプションが使用される可能性があるため、いくつかの誤った結果が生じる場合があります。解決策は、オプションオブジェクトをクローン化し、すべての属性を新しいオブジェクトにコピーし、新しいオブジェクトに変更することです。
この問題を継承で解決する方法は? PSオプションは設定を追加できますが、削除することはできません。
解決
オプションを継承し、サブクラスに新しいプロパティを変更または追加できます。
function enternit(proto){function f(){} f.prototype = proto return new f} function menu(options){var opts = enternit(options)opts.width = opts.width || 300 // ...}すべての操作は、サブオブジェクトでのみ有効です。メニューメソッドが終了すると、外部コードは変更されていないオプションオブジェクトを使用できます。ここでは、削除操作が非常に重要です。幅がプロトタイプ内のプロパティである場合、opts.widthが効果がありません
5。HasownProperty
すべてのオブジェクトには、プロパティがそれ自体かプロトタイプかを検出するために使用できます。
栗:
function rabbit(name){this.name = name} rabbit.prototype = {eats:true} var rabbit = new rabbit( 'john')alert(rabbit.hasownproperty( 'eat'))// false、in prototypealert(rabbit.hasownoperty( 'name'))// true in true、6.継承されたプロパティの有無にかかわらずループ
for。ループは、独自のプロトタイプを含むオブジェクトのすべてのプロパティを出力します。
function rabbit(name){this.name = name} rabbit.prototype = {eats:true} var rabbit = new rabbit( 'john')for(var p in rabbit){alert(p + "=" + rabbit [p])//出力「名前」と「eats」の両方の出力HasownPropertyを使用して、オブジェクトのプロパティをフィルタリングします。
function rabbit(name){this.name = name} rabbit.prototype = {eats:true} var rabbit = new rabbit( 'john')for(var p in rabbit){if(!rabbit.hasownproperty(p))継続//フィルターアウト「eats "= p +" = " + rabbit [p]" " + rabbit [p]" " + rabbitのみ」7。概要
JavaScriptは、特別な属性プロトを介して継承を実装します
オブジェクトのプロパティにアクセスすると、通訳者がオブジェクト内でそれを見つけることができない場合、関数プロパティを探し続けます。これは、プロトタイプではなくオブジェクトを指します。
obj.prop = valueを割り当て、obj.propを削除します
protoの管理:
ChromeとFirefoxは、オブジェクトの__Proto__属性に直接アクセスできます。ほとんどの最新のブラウザは、object.getPrototypeof(OBJ)を使用した読み取り専用アクセスをサポートしています。
object.create(proto)は、指定されたprotoで空の子オブジェクトを生成したり、次のコードで同じ関数を達成したりできます。
function enternit(proto){function f(){} f.prototype = proto return new f()}}その他の方法:
for .. inループは、オブジェクトのすべてのプロパティ(独自のプロトタイプを含む)とオブジェクトのプロトタイプチェーンを出力します。
プロパティプロップがオブジェクトobjに属している場合、obj.hasownproperty(prop)がtrueを返します。