Javascriptはコンストラクション関数を単純なファクトリに拡張
5388 ワード
一般的にJavascriptでオブジェクトを作成する際にはキーワードnew(コンストラクション関数別に呼び出す)を使用する必要がありますが、開発者はnewキーワードが明示的に使用されているかどうかにかかわらず、コンストラクション関数が正常に呼び出されることを望んでいます.すなわち、コンストラクション関数は単純な工場の機能も備えています.Javascriptの1つの特性はこのような「単純なファクトリ式の構造関数」を実行可能にした:構造関数にオブジェクトが返された場合、newキーワードを使用するかどうかにかかわらず、最終的に返される値は関数returnの値である.
この点の特性に基づいて、本文は4種類の実現方式を紹介して、レンガを投げて玉を引いて、レンガを撮ることを歓迎します~
1.コンストラクション関数でオブジェクトの字面量を返す
欠点:prototypeプロパティの制御が不便で、効率的な拡張オブジェクトメソッドに不利で、instanceofオペレータが失効し、constructorプロパティが失われる
2.コンストラクション関数で内部関数を使用してオブジェクトを構築する
欠点:符号化は比較的複雑で、必要とする.Personは補助的な内部構造関数としてprototypeやconstructorなどの属性を手動で変更する必要がある
3.instanceofオペレータの利用
欠点:this instanceof Personを判断する際にコンストラクション関数名Personを指定する必要があり、抽象度が高くなく、コンストラクション関数名を変更する際に手動で文を変更する必要がある
4.callee属性とconstructor属性を利用する
欠点:strictモードではcalleeプロパティを使用できません
(全文完了)
この点の特性に基づいて、本文は4種類の実現方式を紹介して、レンガを投げて玉を引いて、レンガを撮ることを歓迎します~
1.コンストラクション関数でオブジェクトの字面量を返す
1 function Person(name) {
2 return {
3 name: name,
4 getName: function () {
5 return this.name;
6 }
7 };
8 }
9 console.log(new Person('Ralph').getName()); //Ralph
10 console.log(Person('Ralph').getName()); //Ralph
欠点:prototypeプロパティの制御が不便で、効率的な拡張オブジェクトメソッドに不利で、instanceofオペレータが失効し、constructorプロパティが失われる
2.コンストラクション関数で内部関数を使用してオブジェクトを構築する
1 function Person(name) {
2 // lazy loading, Person _Person
3 if (!Person.inited) {
4 Person._Person = function (name) {
5 this.name = name;
6 };
7 // prototype
8 Person._Person.prototype = {
9 // constructor
10 constructor: Person,
11 getName: function () {
12 return this.name;
13 }
14 };
15 // instanceof
16 Person.prototype = Person._Person.prototype;
17 //
18 Person.inited = true;
19 }
20 return new Person._Person(name);
21 }
22 console.log(new Person('Ralph').getName()); //Ralph
23 console.log(Person('Ralph').getName()); //Ralph
欠点:符号化は比較的複雑で、必要とする.Personは補助的な内部構造関数としてprototypeやconstructorなどの属性を手動で変更する必要がある
3.instanceofオペレータの利用
1 function Person(name) {
2 // new,this Person
3 // Person new, this window
4 if (!(this instanceof Person)) {
5 return new Person(name);
6 }
7 this.name = name;
8 }
9 Person.prototype.getName = function () {
10 return this.name;
11 };
12 console.log(new Person('Ralph').getName()); //Ralph
13 console.log(Person('Ralph').getName()); //Ralph
欠点:this instanceof Personを判断する際にコンストラクション関数名Personを指定する必要があり、抽象度が高くなく、コンストラクション関数名を変更する際に手動で文を変更する必要がある
4.callee属性とconstructor属性を利用する
1 function Person(name) {
2 // arguments.callee Person
3 // this.constructor new Person
4 if (arguments.callee !== this.constructor) {
5 return new arguments.callee(name);
6 }
7 this.name = name;
8 }
9 Person.prototype.getName = function () {
10 return this.name;
11 };
12 console.log(new Person('Ralph').getName()); //Ralph
13 console.log(Person('Ralph').getName()); //Ralph
欠点:strictモードではcalleeプロパティを使用できません
(全文完了)