banner
lzyoo

lzyoo

本人职业:前端开发工程师 工作年限:三年 技术栈:React、Vue、Nest、Python 一直在努力,一直在放弃,好想有一个引路人带领。

QTNNDの頭を悩ませるプロトタイプチェーン

😍原型链の紹介#

原型オブジェクト#

簡単な説明をします

JS ではすべてがオブジェクトに基づいています

  • 関数のprototypeは原型オブジェクトを指します
  • 原型オブジェクトのconstructorは関数を指します
  • 原型オブジェクトに定義されたプロパティメソッドは、関連するすべてのインスタンスオブジェクトで共有および継承されます
  • prototype関数固有のものです
  • __proto__プロパティは、オブジェクト固有のものです
  1. JS で関数を作成すると、prototypeプロパティが生成され、このプロパティはオブジェクトを指します。このオブジェクトは、その関数の原型オブジェクトです。

  2. この関数のインスタンスオブジェクトを宣言すると、このオブジェクトは__proto__プロパティを実装し、この__proto__プロパティは、このインスタンスオブジェクト(ha)原型オブジェクト({constructor:f})を指します。したがって、関数のprototypeとインスタンスオブジェクトの__proto__を等しく比較すると、もちろんtrueになります。

// Haという名前の関数を作成します
function Ha(){
    this.name='哈喇'
}
// Haのprototypeを呼び出します
Ha.prototype //{constructor:f}

// インスタンスオブジェクトを宣言します
let ha = new Ha()
// 原型オブジェクトの比較
ha.__proto__ === Ha.prototype // true
// コンストラクタはha.constructorを直接呼び出すことができます
ha.__proto__.constructor === ha.constructor

原型チェーン#

原型チェーンは非常にシンプルです。以下のコードを見れば理解できます。

ha.__proto__.__proto__.__proto__ // null
// ここでnullになる理由を説明します
ha.__proto__はHaの原型オブジェクトを指します
ha.__proto__.__proto__はHaの原型オブジェクトObjectの原型オブジェクトを指します
ha.__proto__.__proto__.__proto__は、すべてがオブジェクトに基づいているので、Objectの上位の原型オブジェクトは存在しますか?もちろん存在しませんので、nullを返します
// コンストラクタの継承
function Haha(name){
    this.name=name
    Ha.call(this)
}

// Hahaクラスのインスタンスをまず宣言し、インスタンスのnameプロパティを呼び出すと、Haのコンストラクタのnameプロパティの値が表示されます。継承を使用しているため、現在のインスタンスのコンストラクタに存在しないプロパティは、上位のHaのコンストラクタのnameプロパティを検索し、存在する場合は表示されます。存在しない場合は、さらに上位のObjectのコンストラクタのnameプロパティを検索し、存在しない場合はnullになります
let haha = new Haha()
haha.name // 哈喇

// Hahaクラスのインスタンスを宣言し、引数を渡して、インスタンスのnameプロパティを呼び出すと、王老五が表示されます
let haha = new Haha('王老五')
haha.name // 王老五

コンストラクタ、インスタンス、および原型の関係#

コンストラクタはインスタンスを作成するための関数です。各インスタンスには原型があり、原型はコンストラクタの原型を指します

// haの原型はHa.prototypeです
// Ha.prototypeの原型はObject.prototypeです
function Ha(){} // コンストラクタ
let ha=new Ha() // インスタンス

Ha.prototype.constructor === Ha //true コンストラクタの原型のconstructorはコンストラクタ自体を指します

継承#

コンストラクタの継承#

call () を使用して Parent の this を Child のインスタンスに指定して継承を実現します。
利点

  1. 親クラスのコンストラクタに引数を渡すことができます。
  2. 同じ親クラスから継承している他の子クラスに影響を与えずに、各子クラスが独自の親クラスインスタンスを持つことができます。

欠点

  1. 親クラスのコンストラクタ内のプロパティとメソッドのみを継承し、原型オブジェクトの内容は継承できません。
  2. 再利用できません
function Parent(){
    this.name='father'
}

Parent.prototype.sayHello = function () {
    return this.name
}

function Children(){
    Parent.call(this)
}
const c = new Children()
c.name // father
c.sayHello // c.sayHello is not a function

原型チェーンの継承#

原型オブジェクトを上書きします

利点

  1. 関数の再利用、子クラスは親クラスのプロパティとメソッドを使用できます。
  2. 子クラスは親クラスの原型オブジェクト上のプロパティとメソッドに直接アクセスできます。

欠点

  1. 親クラスのコンストラクタに引数を渡すことはできません。
  2. 親クラスの参照プロパティは、すべての子クラスに共有され、1 つの子クラスが参照プロパティを変更すると、他の子クラスも影響を受けます。これは同じメモリアドレスを操作しているためです。
  3. 親クラスのプライベート変数が子クラスで公開されます。
function Parent(){
    this.name='father'
    this.hobby = ['唱', '跳']
}
Parent.prototype.sayHello = function(){
    return this.name
}
function Children(){}
Children.prototype = new Parent()
const c = new Children()
const c2 = new Children()
c.name // father
c.sayHello() // father
c.hobby.push('rap')
c.hobby // ['唱', '跳', 'rap']
c2.hobby // ['唱', '跳', 'rap']

コンビネーション継承#

コンストラクタ + 原型チェーン

利点

  1. 親クラスのインスタンスプロパティと原型オブジェクトのすべてのプロパティとメソッド(プライベートを除く)を継承します。
  2. 参照型のプロパティがすべてのインスタンスで共有される問題(原型チェーン継承)を回避します。

欠点

  1. 親クラスのインスタンスを 2 回呼び出すため、パフォーマンスに影響を与えます。
function Parent(){
    this.name='father'
}
Parent.prototype.sayHello = function(){
    return this.name
}
function Children(){
    Parent.call(this)
}
Children.prototype = new Parent()
Children.prototype.constructor = Children
const c = new Children()
c.name // father
c.sayHello() // father

パラサイト継承#

原型式継承 + オブジェクトの拡張

利点

  1. 親クラスのインスタンスプロパティと原型オブジェクトのすべてのプロパティとメソッド(プライベートを除く)を継承します。
  2. 参照型のプロパティがすべてのインスタンスで共有される問題(原型チェーン継承)を回避します。

欠点

  1. 親クラスのインスタンスを 2 回呼び出すため、パフォーマンスに影響を与えます。
function Parent() {
    this.name = 'father'
    this.hobby = ['唱', '跳']
}

Parent.prototype.sayHello = function () {
    return this.name
}

function Children() {
    let parent = new Parent()
    parent.sayBye = function Bye() {
        return this
    }
    return parent
}
const c = new Children()
console.log(c.sayHello());

パラサイトコンビネーション継承#

パラサイト継承 + コンビネーション継承

利点

  1. 親クラスのインスタンスプロパティと原型オブジェクトのすべてのプロパティとメソッド(プライベートを除く)を継承します。
  2. 参照型のプロパティがすべてのインスタンスで共有される問題(原型チェーン継承)を回避します。
  3. Parent コンストラクタを 1 回だけ呼び出します

欠点

  1. 親クラスのインスタンスを 2 回呼び出すため、パフォーマンスに影響を与えます
function _extends(children, parent) {
    let parent_prototype = Object.create(parent.prototype)
    parent_prototype.constructor = children
    children.prototype = parent_prototype
}
function Parent() {
    this.name = 'father'
    this.hobby = ['唱', '跳']
}
Parent.prototype.sayHello = function () {
    return this.name
}
function Children() {
    Parent.call(this)
}

_extends(Children, Parent)
const c = new Children()
console.log(c.sayHello()) // father
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。