この記事では、参考のために JavaScript でオブジェクトを作成する 9 つの方法を紹介します。具体的な内容は次のとおりです。
【1】オブジェクトコンストラクターを使用する
[短所] 同じインターフェースを使用して多数のオブジェクトを作成すると、重複したコードが大量に生成されます
var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }
【2】オブジェクトリテラルを使用する
[短所] 同じインターフェースを使用して多数のオブジェクトを作成すると、重複したコードが大量に生成されます
var person = { name: "Nicholas", age : 29, job: "Software Engineer", sayName: function(){ alert(this.name); } };
【3】ファクトリパターン: 特定のオブジェクトを作成するプロセスを抽象化する ECMAScript ではクラスを作成できないことを考慮して、開発者はオブジェクトの作成の詳細を特定のインターフェイスでカプセル化する関数を発明しました。
【短所】類似オブジェクトを複数作成する問題は解決したが、オブジェクト認識の問題は解決できなかった
function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayname = function(){ alert(this.name); } return o; } var person1 = createPerson('Nicholas',29,'software Engineer'); var person2 = createPerson('greg',27,'doctor');
【4】コンストラクターモード: オブジェクトは明示的に作成されず、属性とメソッドはこのオブジェクトに直接割り当てられ、return ステートメントはありません
[デメリット] インスタンスごとに各メソッドを再作成する必要がある
function Person(name,age,job){ this.name = name; this.age = age; this.jog = job; this.sayName = function(){ alert(this.name); }; //与声明函数在逻辑上是等价的 //this.sayName = new Function('alert(this.name)'); } var person1 = new Person("Nicholas",29,"software Engineer"); var person2 = new Person("Greg",27,"doctor");
【4.1】コンストラクター拡張モード: コンストラクター外での伝達関数定義
[欠点 1] グローバル スコープで定義された関数は、実際には特定のオブジェクトによってのみ呼び出すことができるため、グローバル スコープはその名前に少しふさわしくないものになります
[欠点 2] オブジェクトで多くのメソッドを定義する必要がある場合、このカスタム参照型にはカプセル化がまったく行われないため、多くのグローバル関数を定義する必要があります。
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person = new Person('小火柴','20','student') person.sayName(); console.log(Person);
を呼び出して作成されるオブジェクト インスタンスのプロトタイプ オブジェクトです。
function Person(){ Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "software Engineer"; Person.prototype.sayName = function(){ alert(this.name); } } var person1 = new Person(); person1.sayName();//"Nicholas" var person2 = new Person(); person2.sayName();//"Nicholas" alert(person1.sayName == person2.sayName);//true
[欠点] この方法でコンストラクター プロパティをリセットすると、その [[Enumerable]] 属性が true に設定されます。デフォルトでは、ネイティブ コンストラクター プロパティは列挙可能ではありません。
function Person(){}; Person.prototype = { constructor : Person, name: "Nicholas", age: 29, job: "software Engineer", sayName : function(){ alert(this.name); } };
function Person(){}; Person.prototype = { name: "Nicholas", age: 29, job: "software Engineer", sayName : function(){ alert(this.name); } }; Object.defineProperty(Person.prototype,"constructor",{ enumerable : false, value : Person });
function Person(){} var friend = new Person(); Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", sayName: function(){ alert(this.name); } }; friend.sayName();//error
function Person(){} Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", friend : ["shelby","Court"], sayName: function(){ alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); alert(person1.friends);//["shelby","Court","Van"]; alert(person2.friends);//["shelby","Court","Van"]; alert(person1.friends === person2.friends);//true
を定義するために使用されるデフォルトのモードです。
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ["shelby","Court"]; } Person.prototype = { constructor: Person, sayName : function(){ alert(this.name); } } var person1 = new Person("Nicholas",29,"Software Engineer"); var person2 = new Person("Greg",27,"Doctor"); person1.friends.push("Van"); alert(person1.friends);// ["shelby","Court","Van"]; alert(person1.friends);// ["shelby","Court"]; alert(person1.friends === person2.friends);//false alert(person1.sayName === person2.sayName);//true
[注意] 動的プロトタイプモードを使用する場合、オブジェクトリテラルを使用してプロトタイプをオーバーライドすることはできません。インスタンスがすでに作成されているときにプロトタイプをオーバーライドすると、既存のインスタンスと新しいインスタンスの間の接続が切断されます
function Person(name,age,job){ //属性 this.name = name; this.age = age; this.job = job; //方法 if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas",29,"Software Engineer"); friend.sayName();
function Person(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; return o; } var friend = new Person("Nicholas",29,"Software Engineer"); friend.sayName();//"Nicholas"
function SpecialArray(){ //创建数组 var values = new Array(); //添加值 values.push.apply(values,arguments); //添加方法 values.toPipedString = function(){ return this.join('|'); }; //返回数组 return values; } var colors = new SpecialArray("red","blue","green"); alert(colors.toPipedString());//"red|blue|green"
function Person(name,age,job){ //创建要返回的对象 var o = new Object(); //可以在这里定义私有变量和函数 //添加方法 o.sayName = function(){ alert(name); }; //返回对象 return o; } //在稳妥模式创建的对象中,除了使用sayName()方法之外,没有其他方法访问name的值 var friend = Person("Nicholas",29,"Software Engineer"); friend.sayName();//"Nicholas"