JS での new の手書き実装

JS での new の手書き実装

⚠ 前提条件:

  • プロトタイプとプロトタイプチェーンを理解する
  • このバインディングを理解する

1 新しいオペレータの紹介

MDN ドキュメント: new演算子は、ユーザー定義のオブジェクト タイプのインスタンス、またはコンストラクターを持つ組み込みオブジェクトのインスタンスを作成します。

クラス Person {
    コンストラクタ(名前) {
        this.name = 名前;
    }
}
// カスタムオブジェクトタイプのインスタンスを作成する const person = new Person('Xiao Ming')
// コンストラクタを使用して組み込みオブジェクトのインスタンスを作成する const date = new Date()


newの役割:オブジェクトのインスタンスを作成する

2 新しいものは何をしましたか?

上で、 newの機能はオブジェクトのインスタンスを作成することだと述べましたが、インスタンスはどのように作成され、内部では何が行われるのでしょうか。

new Person() を例に挙げてみましょう。これを実行すると、次のことが起こります。

空のシンプルなJSオブジェクトを作成する

定数オブジェクト = {}


このオブジェクトに属性__proto__,を追加し、その属性をコンストラクタのプロトタイプオブジェクトにリンクします。

obj.__proto__ = Person.プロトタイプ


コンストラクタPersonを呼び出し、 this新しく作成されたオブジェクトobjにバインドします。

Person.apply(オブジェクト)


コンストラクタが明示的にオブジェクトを返さない場合は、新しく作成されたオブジェクト、つまりobjが返されます。

3 新しい演算子の実装をシミュレートする

上で述べたように、 new演算子は 4 つのことを行います。関数を使用して、これらの 4 つの手順に従ってnewの実装をシミュレートしてみましょう (インタビュー用の手書きコード)

const _new = 関数(コンストラクタ、...引数) {
    定数オブジェクト = {}
    obj.__proto__ = コンストラクタ.prototype
    const res = コンストラクタ.apply(obj, args)
    // この手順については「補足」で詳しく説明します return res instanceof Object ? res : obj
}

コードは非常にシンプルで、上記の4つの手順に従って段階的に記述するだけです。

4 補足

ES5にはObject.createメソッドが用意されており、これを使用するとオブジェクトを作成し、新しいオブジェクトの__proto__プロパティが既存のオブジェクトを指すようにすることができます。

この方法を使ってステップ1と2を組み合わせることができます

const obj = Object.create(コンストラクタ.プロトタイプ)
// const obj = {} と同等
obj.__proto__ = コンストラクタ.prototype

ステップ4では、

  • コンストラクターが明示的にreturnない場合 (通常)、 personは新しく作成されたオブジェクトobj
  • コンストラクタが1や「abc」などのオブジェクトを返さない場合、 person新しく作成されたオブジェクトobjのままです。
関数Person() {
    ...
   戻り値 1
}

コンストラクタが明示的にオブジェクトを返す場合(例: {}function() {}

この場合、 person新しく作成されたオブジェクトobjではなく、明示的にreturnオブジェクトになります。

関数Person() {
  // 関数もオブジェクトです return function() {}
}

したがって、_new 関数の最後のコード行は次のようになります。

res インスタンスオブオブジェクトを返します? res : obj


注:シミュレートされた関数_newに渡されるパラメータは、クラスではなくコンストラクタのみです。

class Animal { ...}_new(Animal) // エラーを報告します: クラスコンストラクタ Animal は 'new' なしでは呼び出せません // クラスは new を使用してのみ作成できます

JS での new の手書き実装に関するこの記事はこれで終わりです。JS でのより関連性の高い new コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JSコンストラクタとインスタンス化およびプロトタイプ導入の関係
  • JavaScriptプロトタイプと例の詳細な説明
  • Js の継承とプロトタイプチェーンを理解するのに役立つ記事
  • JavaScriptプロトタイプチェーン図のまとめと実践
  • JS の new 関数の詳細な説明
  • JavaScript のコンストラクター、プロトタイプ、プロトタイプ チェーン、new についてどれくらい知っていますか?

<<:  Html、sHtml、XHtml の違いのまとめ

>>:  MySQL InnoDB ストレージエンジンのメモリ管理の詳細な説明

推薦する

CSS 透明ボーダー背景クリップマジック

この記事では、CSSの透明な境界線の背景クリップの素晴らしい使い方を主に紹介し、みんなと共有し、自分...

Vueはドラッグ可能なツリー構造図を実装します

目次Vue 再帰コンポーネントドラッグイベント最近、Vue を使用して、ドラッグ可能なツリー構造図と...

MySQLとRedisキャッシュ間の同期ソリューションについての簡単な説明

目次1. ソリューション 1 (UDF)デモケース2. ソリューション2(binlogの解析)キャナ...

Vue はシームレスなカルーセル効果を実現

この記事では、シームレスなカルーセル効果を実現するためのVueの具体的なコードを参考までに紹介します...

Vue でインデックスをキー属性値として使用することが推奨されないのはなぜですか?

目次序文キーの役割差分アルゴリズムにおけるキーの役割ヘッドノードを同期するテールノードを同期する新し...

Windows での MySQL データベースのマスター/スレーブ構成チュートリアル

WindowsでMySQLデータベースのマスターとスレーブを構成する詳細なプロセスは次のとおりです。...

フックを使用して React コンポーネントを書くときに注意すべき 5 つの点

目次01. レンダリングが不要な場合はuseStateを使用する02. リンクの代わりにrouter...

vue3でDOMをマウントするためのプラグインを書く際の問題について

vue2と比較して、vue3にはアプリの概念が追加され、vue3プロジェクトの作成も // メイン....

MySQL における一般的な高度な SQL ステートメント

MySQL 高度な SQL ステートメント kgc を使用します。 テーブルlocation(Reg...

Nginx の realip モジュールの使い方の基礎学習

序文nginx モジュールには、公式とサードパーティの 2 種類があります。nginx のインストー...

DockerとFastDFSのインストールコマンドと使い方の詳しい説明

Dockerの機能1) すぐに始められるユーザーがプログラムを「Docker 化」するには、わずか数...

MySQLトリガーはPHPプロジェクトで情報のバックアップ、復元、クリアに使用されます。

例: PHP バックグラウンド コードを通じて、従業員情報を削除したり、削除した従業員情報を復元した...

UCenter ホームサイトに統計コードを追加

UCenter Homeは、ComsenzがリリースしたSNSサイト構築システムです。最新バージョン...

MySQLはtruncateコマンドを使用してデータベース内のすべてのテーブルを素早くクリアします

1. まずSELECT文を実行して、すべての切り捨て文を生成します。ステートメント形式: selec...

MySQL 5.7 データベースのインストール手順の個人的な要約

1.mysql-5.7.19-winx64.zip(これは無料のインストールバージョンで、約318 ...