検索
ホームページウェブフロントエンドjsチュートリアルJavaScript でオブジェクトを作成するさまざまなモードの分析 (グラフィック チュートリアル)

ここで、JavaScript でオブジェクトを作成するためのさまざまなパターンの分析をお届けします。共有して参考にしてください

JavaScriptでのオブジェクトの作成

•ファクトリパターン

•コンストラクターパターン

•プロトタイプパターン

•コンストラクターとプロトタイプのパターンの組み合わせ

•プロトタイプの動的パターン

ほとんどのオブジェクト指向言語にはクラスの概念があり、それを通じて同じメソッドとプロパティを持つ複数のオブジェクトを作成できます。技術的に言えば、JavaScript はオブジェクト指向言語ですが、JavaScript にはクラスの概念がなく、すべてがオブジェクトです。すべてのオブジェクトは、既存の参照型を通じて作成される特定の参照型のインスタンスです。参照型はネイティブまたはカスタマイズできます。ネイティブ参照タイプには、オブジェクト、配列、データ、正規表現、および関数が含まれます。 !参照型は、データと機能を編成するデータ構造であり、多くの場合クラスと呼ばれます。 クラスの概念がない JavaScript では、オブジェクトをいかに効率的に作成するかが解決すべき問題となります。

1.1.0. オブジェクトを作成する一般的なメソッド

var person = {}; //对象字面量表示,等同于var person = new Objcect();
person.name = 'evansdiy';
person.age = '22';
person.friends = ['ajiao','tiantian','pangzi'];
person.logName = function() {
  console.log(this.name);
}

オブジェクト参照型に基づいて、4 つのプロパティを含むオブジェクトが作成され、そのうちの 1 つはメソッドです。人物のようなオブジェクトのインスタンスが多数必要な場合、重複するコードが大量に存在することになります。

1.1.1. ファクトリパターン

オブジェクトの詳細を含むことができる関数を通じてオブジェクトを作成し、そのオブジェクトを返します。

function person(name,age,friends) {

  var o = {
    name: name,
    age: age,
    friends: friends,
    logName: function() {
      console.log(this.name);
    }
  };

  return o;

}

var person1 = person('Evansdiy','22',['ajiao','tiantian','pangzi']);

person 関数が呼び出されるたびに、関数内のオブジェクト o を通じて新しいオブジェクトが作成され、返されます。これ以外に、新しいオブジェクトを作成するために存在するこの内部オブジェクト o には他の目的はありません。さらに、ファクトリ パターンによって作成されたオブジェクトの種類を判断することはできません。

1.1.2. コンストラクター パターン

function Person(name,age,job) {

  this.name = name;
  this.age = age;
  this.job = job;
  this.logName = function() {
    console.log(this.name);
  }

}

//通过new操作符创建Person的实例
var person1 = new Person('boy-a','22','worker');

var person2 = new Person('girl-b','23','teacher');

person1.logName(); //boy-a

person2.logName(); //girl-a

ファクトリ パターンを比較すると、ここでは中間オブジェクトを作成する必要がなく、リターンがないことがわかります。さらに、コンストラクターのインスタンスを特定の型として識別できるため、オブジェクト識別の問題が解決されます (インスタンスのコンストラクター プロパティを確認するか、instanceof 演算子を使用してインスタンスが特定のコンストラクターを通じて作成されたかどうかを確認することによって)。 。

console.log(person1.constructor == Person);//コンストラクターはコンストラクターのプロトタイプ内にあり、コンストラクターを指しており、結果は true です

console.log(person1instanceof Person);// instanceof 演算子 person1 がコンストラクター person のインスタンスであるかどうか。ただし、コンストラクター パターンにも独自の問題があります。インスタンス化によって作成されたメソッドは同じではないことに注意してください。コードは false になります:

console.log(person1.logName == person2.logName); //false この問題を解決するには、メソッドをコンストラクターの外に移動します (グローバル関数になります)。グローバル コンテキストの下で作成されたグローバル関数は、実際には Person によって作成されたインスタンスによってのみ呼び出すことができます。これはその名前に少しふさわしくありません。メソッドが多数ある場合、それらを 1 つずつ定義する必要があり、カプセル化が不足しています。

1.1.3. プロトタイプ モード

JavaScript のすべての関数には、プロトタイプ属性へのポインターが含まれています (ほとんどのブラウザーは、内部属性 __proto__ を通じてアクセスできます)。プロトタイプ属性は、すべての関数で共有されるプロパティとメソッドを含むオブジェクトです。参照型によって作成されたインスタンス。

function logName() {
  console.log(this.name);
}

function logAge() {
  console.log(this.age);
}

上記のコードは次のことを行います:

1. コンストラクター関数 person を定義します。これには、デフォルトでは

を指すコンストラクター属性のみが含まれます。 3 つのプロパティを追加し、そのうちの 1 つはメソッドとして機能します。

3. Person のインスタンスを作成し、そのインスタンスで logName() メソッドを呼び出します。 !

ここで注意する必要があるのは、logName() メソッドの呼び出しプロセスです:

1. person1 インスタンスで logName() メソッドを検索すると、そのようなメソッドがないことがわかり、プロトタイプまでトレースバックします。 person1 のプロトタイプを検索する logame() メソッドにはこのメソッドがあり、このメソッドを呼び出すことで、プロトタイプの同じ名前の属性にインスタンスがアクセスすることを防ぐことができます。インスタンス上のプロトタイプ内の同じ名前の属性。この際、プロトタイプ上の同じ名前のプロパティは削除されず、インスタンスへのアクセスが禁止されるだけであることに注意してください。

var person2 = new Person();

person2.name = 'laocai'; インスタンスの属性が不要になった場合は、delete 演算子を使用して削除できます。

delete person2.name; for-in ループを使用して、インスタンスによってアクセスできるすべてのプロパティ (プロパティがインスタンスに存在するかプロトタイプに存在するかに関係なく) を列挙します。 hasOwnProperty() メソッドは、属性がインスタンス上に存在するか、プロトタイプ内に存在するかを判断します。属性がインスタンス内に存在する場合にのみ true が返されます。

console.log(person1.hasOwnProperty('name'));//true!hasOwnProperty来自Object的原型,是javascript中唯一一个在处理属性时不查找原型链的方法。[via javascript秘密花园] 另外,也可以通过同时使用in操作符和hasOwnProperty()方法来判断某个属性存在于实例中还是存在于原型中:

console.log(('friends' in person1) && !person1.hasOwnProperty('friends'));先判断person1是否可以访问到friends属性,如果可以,再判断这个属性是否存在于实例当中(注意前面的!),如果不存在于实例中,就说明这个属性存在于原型中。 前面提到,原型也是对象,所以我们可以用对象字面量表示法书写原型,之前为原型添加代码的写法可以修改为:

Person.prototype = {

  name: 'evansdiy',
  friends: ['ajiao','jianjian','pangzi'],
  logName: function() {
    console.log(this.name);
  }

}

由于对象字面量语法重写了整个prototype原型,原先创建构造函数时默认取得的constructor属性会指向Object构造函数:

//对象字面量重写原型之后
console.log(person1.constructor);//Object不过,instanceof操作符仍会返回希望的结果:

//对象字面量重写原型之后
console.log(person1 instanceof Person);//true当然,可以在原型中手动设置constructor的值来解决这个问题。

Person.prototype = {

  constructor: Person,
  ......

}

如果在创建对象实例之后修改原型对象,那么对原型的修改会立即在所有对象实例中反映出来:

function Person() {};

var person1 = new Person();

Person.prototype.name = 'evansdiy';

console.log(person1.name);//'evansdiy'

实例和原型之间的连接仅仅是一个指针,而不是一个原型的拷贝,在原型实际上是一次搜索过程,对原型对象的所做的任何修改都会在所有对象实例中反映出来,就算在创建实例之后修改原型,也是如此。 如果在创建对象实例之后重写原型对象,情况又会如何?

function Person() {};

var person1 = new Person1();//创建的实例引用的是最初的原型

//重写了原型
Person.prototype = {
  friends: ['ajiao','jianjian','pangzi']
}

var person2 = new Person();//这个实例引用新的原型

console.log(person2.friends);

console.log(person1.friends);

以上代码在执行到最后一行时会出现未定义错误,如果我们用for-in循环枚举person1中的可访问属性时,会发现,里头空无一物,但是person2却可以访问到原型上的friends属性。 !重写原型切断了现有原型与之前创建的所有对象实例的联系,之前创建的对象实例的原型还在,只不过是旧的。

//创建person1时,原型对象还未被重写,因此,原型对象中的constructor还是默认的Person()
console.log(person1.constructor);//Person()

//但是person2的constructor指向Object()
console.log(person2.constructor);//Object()

需要注意的是,原型模式忽略了为构造函数传递参数的过程,所有的实例都取得相同的属性值。同时,原型模式还存在着一个很大的问题,就是原型对象中的引用类型值会被所有实例共享,对引用类型值的修改,也会反映到所有对象实例当中。

function Person() {};

Person.prototype = {
  friends: ['ajiao','tiantian','pangzi']
}

var person1 = new Person();

var person2 = new Person();

person1.friends.push('laocai');

console.log(person2.friends);//['ajiao','tiantian','pangzi','laocai']

修改person1的引用类型值friends,意味着person2中的friends也会发生变化,实际上,原型中保存的friends实际上只是一个指向堆中friends值的指针(这个指针的长度是固定的,保存在栈中),实例通过原型访问引用类型值时,也是按指针访问,而不是访问各自实例上的副本(这样的副本并不存在)。

1.1.4.结合构造函数和原型模式创建对象

结合构造函数和原型模式的优点,弥补各自的不足,利用构造函数传递初始化参数,在其中定义实例属性,利用原型定义公用方法和公共属性,该模式应用最为广泛。

function Person(name,age) {

  this.name = name;
  this.age = age;
  this.friends = ['ajiao','jianjian','pangzi'];

}

Person.prototype = {

  constructor: Person,
  logName: function() {
    console.log(this.name);
  }

}

var person1 = new Person('evansdiy','22');

var person2 = new Person('amy','21');

person1.logName();//'evansdiy'

person1.friends.push('haixao');

console.log(person2.friends.length);//3

1.1.5.原型动态模式

原型动态模式将需要的所有信息都封装到构造函数中,通过if语句判断原型中的某个属性是否存在,若不存在(在第一次调用这个构造函数的时候),执行if语句内部的原型初始化代码。

function Person(name,age) {

  this.name = name;
  this.age = age;

  if(typeof this.logName != 'function') {
    Person.prototype.logName = function() {
      console.log(this.name);
    };
    Person.prototype.logAge = function() {
      console.log(this.age);
    };
  };

}

var person1 = new Person('evansdiy','22');//初次调用构造函数,此时修改了原型

var person2 = new Person('amy','21');//此时logName()方法已经存在,不会再修改原型

需要注意的是,该模式不能使用对象字面量语法书写原型对象(这样会重写原型对象)。若重写原型,那么通过构造函数创建的第一实例可以访问的原型对象不会包含if语句中的原型对象属性。

function Person(name,age) {

  this.name = name;
  this.age = age;

  if(typeof this.logName != 'function') {
    Person.prototype = {
      logName: function() {
        console.log(this.name);
      },
      logAge: function() {
        console.log(this.Age);
      }
    }
  };

}

var person1 = new Person('evansdiy','22');

var person2 = new Person('amy','21');

person2.logName();//'amy'

person1.logName();//logName()方法不存在

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

详细解读JavaScript设计模式开发中的桥接模式(高级篇)

详细解读在JavaScript中实现设计模式中的适配器模式的方法(图文教程)

设计模式中的facade外观模式在JavaScript开发中的运用(高级篇)

以上がJavaScript でオブジェクトを作成するさまざまなモードの分析 (グラフィック チュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。