ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptでオブジェクトを作成する方法のまとめ(超定番)

JavaScriptでオブジェクトを作成する方法のまとめ(超定番)

不言
不言オリジナル
2018-08-29 16:28:391100ブラウズ

この記事は、JavaScript でオブジェクトを作成する方法をまとめたものです。必要な方は参考にしていただければ幸いです。

JavaScript でオブジェクトを作成する方法はたくさんあります。オブジェクト コンストラクターまたはオブジェクト リテラルを使用して単一のオブジェクトを作成することもできます。明らかに、これら 2 つの方法では大量の繰り返しコードが生成されるため、大量生産には適していません。次に、オブジェクトを作成するための 7 つの非常に古典的な方法を紹介します。それぞれに独自の長所と短所があります。 (内容は主に「JavaScript Advanced Programming」からのもので、他の人が書いた記事も参照しています)

1. ファクトリモード

function createPerson(name, job) { 
 var o = new Object() ;
 o.name = name ;
 o.job = job ;
 o.sayName = function() { 
  console.log(this.name) 
 } 
 return o 
} 
var person1 = createPerson('Mike', 'student') 
var person2 = createPerson('X', 'engineer')

このファクトリ関数は何度でも呼び出すことができ、毎回次の内容を含む関数が返されます。 2 つの属性とメソッド オブジェクト。
ファクトリ パターンは、類似したオブジェクトを複数作成するという問題は解決しますが、オブジェクトの識別の問題は解決しません。つまり、オブジェクトの種類を知ることができません。

2. コンストラクターモード

function Person(name, job) { 
 this.name = name ;
 this.job = job ;
 this.sayName = function() { 
  console.log(this.name) 
 } 
} 
var person1 = new Person('Mike', 'student') 
var person2 = new Person('X', 'engineer')

このコンストラクターを呼び出すには new を使用します。
① 新しいオブジェクトを作成します。
② スコープを変更します。コンストラクター 新しいオブジェクトに代入します (つまり、これは新しいオブジェクトを指します);
③コンストラクター内のコードを実行します (新しいオブジェクトに属性を追加します);
④新しいオブジェクトを返します。
欠点: 各インスタンスで各メソッドを再作成する必要があります。
同じタスクを完了する 2 つの Function インスタンスを作成する必要はありません。さらに、このオブジェクトを使用すると、コードを実行する前に関数を特定のオブジェクトにバインドする必要がなく、次の形式で定義できます。

function Person( name, age, job ){
    this.name = name;
    this.age = age;
    this.job = job;

    this.sayName = sayName;
}

function sayName(){
    alert( this.name );
}

このようにして、sayName() 関数の定義を に転送できます。外部コンストラクター。コンストラクター内で、sayName プロパティをグローバルのsayName 関数に設定します。この場合、sayName には関数へのポインタが含まれるため、person1 オブジェクトと person2 オブジェクトは、グローバル スコープで定義された同じ SayName() 関数を共有できます。

これにより、同じことを行う 2 つの関数の問題は解決されましたが、新しい問題が発生します。グローバル スコープで定義された関数は、実際には特定のオブジェクトによってのみ呼び出すことができるため、グローバル スコープはその名前に少しふさわしくないものになります。さらに重要なことは、オブジェクトで多くのメソッドを定義する必要がある場合、多くのグローバル関数を定義する必要があることです。このように、カスタマイズされた参照型にはカプセル化がまったくありません。

これらの問題は、プロトタイプ モードを使用することで解決できます。

3. プロトタイプモード

function Person() { 
} 
Person.prototype.name = 'Mike' 
Person.prototype.job = 'student' 
Person.prototype.sayName = function() { 
 console.log(this.name) 
} 
var person1 = new Person()

プロトタイプオブジェクトに情報を直接追加します。プロトタイプを使用する利点は、すべてのインスタンス オブジェクトがそれに含まれるプロパティとメソッドを共有できることです。コンストラクターでオブジェクト インスタンス情報を定義する代わりに、この情報をプロトタイプ オブジェクトに直接追加できます。
①プロトタイプを理解する
新しい関数が作成されるたびに、特定のルールに従ってその関数のプロトタイプ属性が作成されます。
デフォルトでは、すべての prototype 属性は、prototype 属性が配置されている関数へのポインターを含む constructor (コンストラクター) 属性を自動的に取得します。
コードがオブジェクトのプロパティを読み取るたびに、指定された名前のプロパティをターゲットとして検索が実行されます。検索はオブジェクト インスタンス自体から始まります。指定された名前の属性がインスタンス内で見つかった場合は、その属性の値が返されます。見つからなかった場合は、ポインタが指すプロトタイプ オブジェクトが検索され、指定された名前の属性がプロトタイプ オブジェクト内で見つかります。このプロパティがプロトタイプ オブジェクトで見つかった場合、このプロパティの値が返されます。
プロトタイプに保存されている値にはオブジェクト インスタンスを通じてアクセスできますが、プロトタイプ内の値をオブジェクト インスタンスを通じてオーバーライドすることはできません。
インスタンスにプロパティを追加し、そのプロパティがインスタンス内のプロパティと同じ名前である場合、そのプロパティはインスタンス内に作成され、そのプロパティはプロトタイプ内のそのプロパティをマスクします。
属性をnullに設定しても、インスタンス内でのみ属性値がnullになります。
ただし、インスタンスのプロパティは削除演算子を使用して完全に削除でき、プロトタイプ内のプロパティに再度アクセスできるようになります。
hasOwnProperty() メソッドを使用して、プロパティがインスタンスに存在するかプロトタイプに存在するかを検出します。このメソッドは、指定されたプロパティがオブジェクト インスタンスに存在する場合にのみ true を返します。

②プロトタイプと in 演算子

in 演算子は、プロパティがインスタンスに存在するかプロトタイプに存在するかに関係なく、オブジェクトを通じて特定のプロパティにアクセスできる場合に true を返します。

③より単純なプロトタイプ構文

function Person(){    
}
Person.prototype = {
    name : "Mike",
    age : 29,
    job : "engineer",

    syaName : function(){
        alert( this.name );
    }
};
//上記のコードでは、 person.prototype は、オブジェクト リテラルの形式で作成された新しいオブジェクトと等しく設定されます。最終結果は同じですが、1 つの例外があります。コンストラクター プロパティは person を指さなくなりました。

4. コンストラクターパターンとプロトタイプパターンの併用

组合使用构造函数模式和原型模式是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点,使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用,这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了。还支持向构造函数传递参数,可谓是集两种模式的优点。

function Person(name) { 
 this.name = name 
 this.friends = ['Jack', 'Merry'] 
} 
Person.prototype.sayName = function() { 
 console.log(this.name) 
} 
var person1 = new Person() 
var person2 = new Person() 
person1.friends.push('Van') 
console.log(person1.friends) //["Jack", "Merry", "Van"] 
console.log(person2.friends) // ["Jack", "Merry"] 
console.log(person1.friends === person2.friends) //false

五、动态原型模式

动态原型模式将所有信息都封装在了构造函数中,初始化的时候。可以通过检测某个应该存在的方法是否有效,来决定是否需要初始化原型。

function Person(name, job) { 
  // 属性 
 this.name = name 
 this.job = job 
 // 方法 
 if(typeof this.sayName !== 'function') { 
  Person.prototype.sayName = function() { 
    console.log(this.name) 
  } 
 } 
} 
var person1 = new Person('Mike', 'Student') 
person1.sayName()

只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。此后原型已经完成初始化,不需要在做什么修改了,这里对原型所做的修改,能够立即在所有实例中得到反映。
其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行。

六、寄生构造函数模式

这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象

function Person(name, job) { 
  var o = new Object() 
 o.name = name 
 o.job = job 
 o.sayName = function() { 
  console.log(this.name) 
 } 
 return o 
} 
var person1 = new Person('Mike', 'student') 
person1.sayName()

这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样。
构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。

七、稳妥构造函数模式

首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用。
稳妥构造函数模式和寄生模式类似,有两点不同:1.是创建对象的实例方法不引用this;2.不使用new操作符调用构造函数

function Person(name, job) { 
 var o = new Object() 
 o.name = name 
 o.job = job 
 o.sayName = function() { 
  console.log(name) 
 } 
 return o 
} 
var person1 = Person('Mike', 'student') 
person1.sayName()

和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义

相关推荐:

JavaScript的中对象创建和继承原理

javascript简单对象创建

以上がJavaScriptでオブジェクトを作成する方法のまとめ(超定番)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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