JS - オブジェクトを作成するにはいくつかの方法(工場出荷時のモード、コンストラクタモード、Prototypeパターン)

逐語https://www.dazhuanlan.com/2019/08/26/5d62f8b594f10/


  • ファクトリパターン
    • 実践:内部オブジェクトを作成し、いないオブジェクトのプロパティの割り当てとリターン
    • 短所:複数のオブジェクトを作成し、問題解決の知人が、作成されたオブジェクトの種類を識別することはできません
  • コンストラクタモード
    • 方法:直接この主題に割り当てられたプロパティとメソッドに、ノーリターン文はありません
    • 短所:オブジェクトは、共通のメソッドとプロパティ、オブジェクトが新しいメモリを作成する必要があるたびに、消費を超えたパフォーマンスではありません
  • プロトタイプモード
    • 実践:プロトタイプを通じてオブジェクトに属性を追加します
    • 短所:各インスタンスは、メソッドの属性を共有し、オブジェクトの属性は、他のインスタンスに影響を与えるインスタンスを変更します
  • そして、組み合わせモードコンストラクタのプロトタイプパターン
    • 練習:インスタンスのプロパティのコンストラクタモードが定義され、プロトタイプモデルを定義するための一般的な方法
    • プロトタイプとブレンドコンストラクタは、より広く使用さ
  • ダイナミックプロトタイプモデル
    • 効果的な存在であるべきであるかどうかを調べることによりこの方法は、元のプロパティかどうかを決定するために初期化される必要があります
  • 寄生コンストラクタモード...

序文

JSオブジェクト指向の最初のステップは何ですか?A:オブジェクトが作成されます。私たちの最も一般的に使用される内にオブジェクトを作成するための多くの方法があり、オブジェクトを作成するオブジェクトリテラルされている、var obj = {}あなたはなぜ、私はそれらの素晴らしいを行う方法を学習し続けなければならない、私はまだオブジェクトを作成しないことを参照してください?私は人々が唯一の良いヘクタールすることができ、いくつかのオブジェクトを検索するために、単一の、マルチマスタに値すると思います。真剣に、ハイエンドのように多くの単語は、オブジェクトリテラル、重大な欠点があり、単一のオブジェクトを作成して使用して、そこにある多くのオブジェクトを作成するために、同じインターフェイスを使用し、重複したコードの多くを生成します。この問題を解決するために、我々は次のことを知っておく必要がありますか?これらの方法を。

ファクトリパターン

1 
2
3
4
5
6
7
8
9
10
11
12
機能名前、年齢、仕事 { VARの O =新しいオブジェクト()  o.name =名前  o.age =年齢  o.job =ジョブ  o.sayName =機能




{
アラート(この .nameの)
} 戻り O } VAR PERSON1 = createPerson('ニコラス'29'ソフトウェアエンジニア'VAR PERSON2 = createPerson('グレッグ'27'医師'




ファクトリーモードは、複数の同様のオブジェクトを作成するための問題を解決するが、オブジェクトを作成したオブジェクトを識別するために、問題の識別方法のタイプが解決されません。モデルのコンストラクタに起因するすべてのオブジェクト、差別のない、日付とは異なり、配列などが、あるので、

コンストラクタモード

1 
2
3
4
5
6
7
8
9
10
関数  {この .nameの=名前この .showName =関数

{
アラート(この .nameの)
}
}
VAR P1 = 新しい人('笑'
p1.showName()
するvar P2 = 新しい人('笑'
p2.showName()

我々は、中人()のコードに注意し
、同じセクション内createPerson()のほかに、次のような違いがあります。

  • 明示的にオブジェクトを作成するわけではありません。
  • 直接このオブジェクトのプロパティとメソッドに割り当てられました。
  • いいえreturn文はありません。

また、大文字P.を使用して、関数名パーソンことに留意すべきです 慣例により、コンストラクタは必ずとすべきである
大文字ではなく、コンストラクタ小文字でなければなりません。このアプローチは、主にするために、他のオブジェクト指向言語から借用
コンストラクタ関数自体は、オブジェクトを作成するために使用することができるので、ECMAScriptの内の他の機能と区別します。
人の新しいインスタンスを作成するには、new演算子を使用する必要があります。この方法では、コンストラクタを呼び出すと、実際に以下の4つのを通過します
手順:

  1. 新しいオブジェクトを作成します。
  2. コンストラクタの範囲は(したがって、これは、新しいオブジェクトを指す)新しいオブジェクトを割り当てます。
  3. (新規オブジェクトのプロパティを追加)コードコンストラクタを実行します。
  4. 新しいオブジェクトを返します。

例えば

1 
2
3
4
5
6
7
8
9
関数  {この .nameの=名前この .showName =関数

{
アラート(この .nameの)
} コンソール .logの(この} 新しい人物('笑'人('母'




私たちは、時間の関数を呼び出すために、新規を使用している場合、この点は異なるものになることがわかります。実際には、新しいは主にこれらの事を、以下の作られたが、ちょうど行動ではなく、内部ソースについては、次を書きました

1 
2
3
4
5
6
7
8
9
10
11
関数  { VAR OBJ = {} //宣言空のオブジェクトOBJ   obj._proto_ = Person.prototype // _proto_このオブジェクトのプロパティは、プロトタイプオブジェクトを呼び出すことができるOBJので、プロトタイプのオブジェクトコンストラクタ関数を指すように人プロトタイプは結論を知っているすべてのメソッド、下、次のように話します。  Person.apply(OBJ) // OBJオブジェクトにこの点作るために使用される方法は適用この .nameのを=名前は、objがプロパティ、メソッドを追加するオブジェクト// この .showName =関数





{
アラート(この .nameの)
} を返す objがオブジェクトを戻す// }


構造モデルの問題の機能があります:

1
GoogleのAlertEND_LINK(p1showName == p2showName)、であることが偽//

2つのオブジェクトがメソッド見え共有されない、すべての新しい時間、新しいメモリを作成するシステムは、二つのオブジェクトそれぞれが自分のサイトを持っているが、彼らは確かに私たちが望んでいないものを、同じ機能、共有されていないがあります。だから、次の方法があり、原型コンフィギュレーションモード== +> Prototypeパターン

プロトタイプモード

我々が有する各機能を作成したprototype(プロトタイプ)プロパティを、このプロパティは、オブジェクトへのポインタであり、このオブジェクトが含む特定のタイプの使用であるすべてのインスタンスによって共有されるプロパティとメソッドことを、理解する文字通りあれば
、それはコンストラクタのプロトタイプオブジェクトのインスタンスを呼び出すことにより、作成したオブジェクトのプロトタイプです。プロトタイプオブジェクトを使用する利点は、
それが共有の例が含まれているすべてのオブジェクトのプロパティとメソッドを作ること。換言すれば、情報は、構成機能の例のオブジェクトを定義する必要はありませんが、
次の例に示すように、情報は、プロトタイプオブジェクトに直接添加することができます。

1 
2
3
4
5
6
7
8
9
10
11
関数  {この .nameの=名}Person.prototype.showName =関数


{
アラート(この .nameの)
}
VAR P1 = 新しい人('笑'
p1.showName()
VAR P2 = 新しい人('笑'
p2.showName()
アラート(p1.showName == p2.showName)//真

テストが真である、目に見えるshowName()メソッドは、それらがメモリを共有することを意味し、共有され、さらに、彼らが参照関係を持っていることを、あなたはshowName P1に変更することもshowName P2に影響し、問題があると述べましたその理由は、我々はほとんど一人で人モードのプロトタイプを見ていないということです。

そして、組み合わせモードコンストラクタのプロトタイプパターン

最も一般的な方法は、モデルとプロトタイプコンストラクタモードの組み合わせを使用することで、カスタム・タイプを作成します。コンストラクタは、実モードを定義するために使用され
たプロトタイプモデルはメソッドおよび共有プロパティを定義するために使用される、特性を実施例。その結果、各インスタンスは、インスタンス属性の独自のコピーを持っていますが、
それと同時に、省メモリを最大化するための方法を参照して共有します。加えて、このモデルはまた、コンストラクタへのハイブリッド伝送パラメータサポート
番号を、長く設定されている2つのモードが説明しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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,Count,Van"
alert(person2.friends) //"Shelby,Count"
alert(person1.friends === person2.friends) //false
alert(person1.sayName === person2.sayName) //true

在这个例子中,实例属性都是在构造函数中定义的,而由所有实例共享的属性 constructor 和方
法 sayName() 则是在原型中定义的。而修改了 person1.friends (向其中添加一个新字符串),并不
会影响到 person2.friends ,因为它们分别引用了不同的数组。

种构造函数与原型混成的模式,是目前在 ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

动态原型模式

有其他 OO 语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑。动态原型模式正是致力于解决这个问题的一个方案,它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。来看一个例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()

注意构造函数代码中 if 判断语句的部分。这里只在 sayName() 方法不存在的情况下,才会将它添加到原
型中。这段代码只会在初次调用构造函数时才会执行。此后,原型已经完成初始化,不需要再做什么修
改了。不过要记住,这里对原型所做的修改,能够立即在所有实例中得到反映。因此,这种方法确实可
以说非常完美。其中, if 语句检查的可以是初始化之后应该存在的任何属性或方法——不必用一大堆
if 语句检查每个属性和每个方法;只要检查其中一个即可。对于采用这种模式创建的对象,还可以使
用 instanceof 操作符确定它的类型。

1
2
3
4
5
6
7
8
9
function Person( {} 
VARの友人= 新しい人()
Person.prototype = { コンストラクタ:人、 sayName:機能(){ 警告(この .nameの) } } friend.sayName()//エラー






寄生コンストラクタモード

...。

おすすめ

転載: www.cnblogs.com/petewell/p/11410433.html