まず明確にしておきたいのは、コンストラクタも関数であるということです。 インスタンス オブジェクトを作成するには、コンストラクターをよく使用します。たとえば、オブジェクトと配列のインスタンス化は、対応するコンストラクター Object() と Array() を通じて完了できます。 コンストラクタと通常の関数の構文定義に違いはありません。主な違いは次の 3 点に反映されます。 (1)コンストラクタ関数名の最初の文字は通常大文字になります。慣例により、コンストラクター名は大文字で始まり、非コンストラクター名は小文字で始まります。これはオブジェクト指向プログラミング言語から借用したもので、ECMAScript でコンストラクターを通常の関数と区別するのに役立ちます。 (2) thisキーワードは、関数本体内で生成するオブジェクトインスタンスを示すために使用されます。コンストラクタは明示的に値を返しませんが、デフォルトで「this」を返します。次のコード スニペットでは、Person() 関数は return キーワードを使用して情報を返しませんが、出力変数 person1 は、name および age 属性値を持つ Person インスタンスです。 <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>ドキュメント</title> </head> <本文> <スクリプト> //1. コンストラクタ関数を定義する Person(name,age){ this.age = 年齢; this.name = 名前; this.sayName = 関数(){ コンソールにログ出力します。 } } // 2. インスタンス オブジェクトを生成します。var person1 = new Person('Xiao Su','18'); // 3. インスタンスオブジェクトを出力します。console.log(person1); </スクリプト> </本文> </html> 表示効果は以下のとおりです (3)コンストラクタとして呼び出される場合は、new演算子と組み合わせて使用する必要があります。これは非常に重要です。new 演算子で呼び出される関数はすべてコンストラクターであり、new 演算子で呼び出されない関数は通常の関数です。 1. コンストラクタの定義と呼び出しコンストラクターはカスタム関数とも呼ばれ、関数の形式で独自のオブジェクト タイプのプロパティとメソッドを定義します。 例: <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>ドキュメント</title> </head> <本文> <スクリプト> //1. コンストラクタ関数を定義する Person(name,age){ this.age = 年齢; this.name = 名前; this.sayName = 関数(){ コンソールにログ出力します。 } } // 2. インスタンス オブジェクトを生成します。var person1 = new Person('Xiao Su','18'); // 3.メソッド person1.sayName() を呼び出します。 </スクリプト> </本文> </html> 2. 新しいキーワードの目的コンストラクターが実行されると、次の 4 つのステップが実行されます。
例として、 person1 インスタンスを生成する前のコードを見てみましょう。 ステップ 1: person1 インスタンスのメモリ内に新しいアドレスを作成します。 ステップ 2: person1 インスタンスの this ポインターが person 自体を指していることを確認します。 ステップ 3: person1 インスタンスに name、age、sayName 属性を追加します。ここで、sayName 属性値は関数です。 ステップ 4: person1 インスタンスを返します。 例 var person1 = new Person("ボブ", 18); このコード行は、 // 新しい関数 Person(name,age) の機能を説明します。 // 1. 新しいオブジェクトを作成する var instance = new Object(); // 2. 関数内の this をこの新しいオブジェクトにポイントします。this = instance; // 3. コンストラクター内のコードを実行します。this.name = name; this.age = 年齢; this.sayName = 関数 () { コンソールにログ出力します。 }; // 4. 新しいオブジェクトを戻り値として返します。 return instance; } これは、インスタンスが person1 に割り当てられる、つまり person1 = インスタンスであることを意味します。実際は次のようになります。 // 新しい関数 Person(name,age) の機能を説明します。 // 1. 新しいオブジェクトを作成する var person1 = new Object(); // 2. 関数内の this をこの新しいオブジェクトにポイントします。this = person1; // 3. コンストラクター内のコードを実行します。this.name = name; this.age = 年齢; this.sayName = 関数 () { コンソールにログ出力します。 }; // 4. 新しいオブジェクトを戻り値として返します。 return person1; } 3. コンストラクタの問題: メモリの無駄基本的な事実: sayName 属性はインスタンスごとに異なります。例えば: <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>ドキュメント</title> </head> <本文> <スクリプト> // 1. カスタムコンストラクター関数 Person(name,age) { this.name = 名前; this.age = 年齢; // この内部の type プロパティ値は変更されません this.type = "human"; // 各オブジェクトの sayName メソッドは同じです this.sayName = function () { コンソールにログ出力します。 }; } var person1 = new Person('Bob',18); var person2 = new Person('Mike',20); // 2. それぞれのメソッドが同じかどうかを判定する function console.log(person1.sayName === person2.sayName); // false </スクリプト> </本文> </html> 説明: console.log(person1.sayName === person2.sayName) メソッドを使用すると、2 つの関数が同じかどうかを判断できます。明らかに、これらは同じ関数ではないため、2 つの関数は 2 つのメモリ領域を占有し、メモリの無駄が発生します。 では、関数がメモリを占有する問題をどのように解決するのでしょうか?答えは、オブジェクトの内部関数を公開関数として抽出することです。 <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>ドキュメント</title> </head> <本文> <スクリプト> // 解決策 1: コンストラクター関数 sayName() からパブリック関数を抽出する { コンソールにログ出力します。 } 関数 sayAge() { コンソールにログ出力します。 } //1. カスタムオブジェクト関数 Person(name,age) { this.name = 名前; this.age = 年齢; // この内部の type プロパティ値は変更されません this.type = "human"; // 各オブジェクトの sayName メソッドは同じです this.sayName = sayName; 年齢を言う } //2. オブジェクトをインスタンス化します var person1 = new Person('Bob',18); var person2 = new Person('Mike',20); console.log(person1.sayName === person2.sayName); // 真 </スクリプト> </本文> </html> この時点でも問題があります。パブリック関数が複数ある場合、外部で複数の関数を作成する必要があり、名前の競合が発生する可能性があります。 解決策: 複数の共通関数を1つのオブジェクトにカプセル化する <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>ドキュメント</title> </head> <本文> <スクリプト> // 3. 複数のパブリック関数を1つのオブジェクトにカプセル化する var fns = { sayName: 関数() { コンソールにログ出力します。 }, sayAge: 関数() { コンソールにログ出力します。 } }; // 1. カスタムオブジェクト関数 Person(name,age) { this.name = 名前; this.age = 年齢; this.type = "人間"; this.sayName = fns.sayName; 年齢を言う = fns.sayAge; } // 2. オブジェクトインスタンスを生成する var person1 = new Person("Bob",18); var person2 = new Person("マイク",20); // person1.sayName(); コンソールにログ出力します。 コンソールに記録します。(person1.sayAge === person2.sayAge); </スクリプト> </本文> </html> 説明: 複数の関数を 1 つのオブジェクトにカプセル化すると、関数名の競合の問題を解決できます。 グローバルにアクセス可能な関数を設定すると、繰り返し作成しなくてもすべてのインスタンスからアクセスできるようになります。 ただし、問題があります。オブジェクトに追加されたすべての関数がグローバル関数として扱われると、カスタム型オブジェクトのプロパティのカプセル化を完了できなくなります (つまり、グローバル関数は関数のみをカプセル化でき、プロパティはカプセル化できません。プロパティは関数の外部でカプセル化され、呼び出す前にグローバル変数として定義する必要があり、グローバル変数が汚染されるためです)。したがって、これは良い解決策ではありません。 この時点で、プロトタイプの概念が導入されます。プロトタイプの概念を使用すると、この問題をうまく解決できます。 要約するこの記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: OpenSSL は双方向認証のチュートリアルを実装します (サーバーとクライアントのコード付き)
以下の記事を読んだ後、プロジェクトをサーバーにデプロイできます。Tomcat、JDK、MySQL な...
1. コンポーネントと実装機能Keepalived: Haproxy サービスの高可用性を実現し、...
序文この記事では、MySQL 8.0 の新機能を使用して再帰クエリを実装します。詳細なサンプル コー...
序文通知バー コンポーネントは、比較的一般的なコンポーネントです。基本的に、すべてのサイトにこのよう...
ページをナビゲートする2つの方法宣言型ナビゲーション: リンクをクリックしてナビゲーションを実現する...
かなりの数のウェブサイトがデジタルページング効果を使用しています。たとえば、このサイトのページングも...
目次前面に書かれたルータ.jsonルート生成メニュー生成効果要約する前面に書かれたルートを繰り返し記...
目次1. --skip-grant-tables 経由で取得する1.1 my.conf を変更し、新...
初めて docker に触れたときは本当に戸惑いました。初心者向けのチュートリアルを長い間読みました...
特記事項:この記事は、Chris Spooner の英語記事「Web デザイン用の Retina グ...
目次序文1. モナドの判断1.1 例1.2 オブジェクトに入れる1.3 マップに載せる2. 複数の判...
GitLabのDocker使用法gitlab ドッカー起動コマンド docker run -d -p...
1. HTML タグを使用してテーブルを作成します。コードをコピーコードは次のとおりです。 <...
場合によっては、Windows システム上のプログラムを Linux 上でリモートで実行する必要があ...
目次1. 時刻表示に関する従来の考え方2. 時刻の書式設定 toLocaleString() Obj...