JavaScriptでオブジェクトを作成する方法について、混乱しています。少なくとも2つの方法があるようです。1つはオブジェクトリテラル表記を使用する方法で、もう1つは構築関数を使用する方法です。どちらか一方の利点はありますか?
JavaScriptでオブジェクトを作成する方法について、混乱しています。少なくとも2つの方法があるようです。1つはオブジェクトリテラル表記を使用する方法で、もう1つは構築関数を使用する方法です。どちらか一方の利点はありますか?
回答:
オブジェクトに関連付けられた動作がない場合(つまり、オブジェクトがデータ/状態のコンテナーにすぎない場合)、オブジェクトリテラルを使用します。
var data = {
foo: 42,
bar: 43
};
KISSの原則を適用します。単純なデータのコンテナー以外に何も必要ない場合は、単純なリテラルを使用します。
オブジェクトに動作を追加する場合は、コンストラクターを使用して、構築中にオブジェクトにメソッドを追加するか、クラスにプロトタイプを与えることができます。
function MyData(foo, bar) {
this.foo = foo;
this.bar = bar;
this.verify = function () {
return this.foo === this.bar;
};
}
// or:
MyData.prototype.verify = function () {
return this.foo === this.bar;
};
このようなクラスは、データオブジェクトのスキーマのようにも機能します。これで、オブジェクトが初期化/保持するプロパティが(コンストラクタを通じて)ある種のコントラクトになります。無料のリテラルは、単なるデータの不定形の塊です。
またverify、プレーンな古いデータオブジェクトに作用する外部関数を使用することもできます。
var data = {
foo: 42,
bar: 43
};
function verify(data) {
return data.foo === data.bar;
}
ただし、これはカプセル化に関しては好ましくありません。理想的には、エンティティに関連付けられたすべてのデータ+動作が共存する必要があります。
this.fn = function ...、コンストラクターでこのアプローチを使用する場合、オブジェクトインスタンスのそれぞれに独自の関数のコピーがあります。プロトタイプアプローチを使用して、各関数を1回だけアタッチします。これらの関数は、プロトタイプの継承を通じてインスタンスによって継承されます。
基本的には、オブジェクトの複数のインスタンスが必要かどうかということになります。コンストラクタで定義されたオブジェクトを使用すると、そのオブジェクトの複数のインスタンスを作成できます。オブジェクトリテラルは、基本的にすべてパブリックな変数/メソッドを持つシングルトンです。
// define the objects:
var objLit = {
x: 0,
y: 0,
z: 0,
add: function () {
return this.x + this.y + this.z;
}
};
var ObjCon = function(_x, _y, _z) {
var x = _x; // private
var y = _y; // private
this.z = _z; // public
this.add = function () {
return x + y + this.z; // note x, y doesn't need this.
};
};
// use the objects:
objLit.x = 3;
objLit.y = 2;
objLit.z = 1;
console.log(objLit.add());
var objConIntance = new ObjCon(5,4,3); // instantiate an objCon
console.log(objConIntance.add());
console.log((new ObjCon(7,8,9)).add()); // another instance of objCon
console.log(objConIntance.add()); // same result, not affected by previous line
均一な方法でオブジェクトを作成するもう1つの方法は、オブジェクトを返す関数を使用することです。
function makeObject() {
var that = {
thisIsPublic: "a public variable"
thisIsAlsoPublic: function () {
alert(that.thisIsPublic);
}
};
var secret = "this is a private variable"
function secretFunction() { // private method
secret += "!"; // can manipulate private variables
that.thisIsPublic = "foo";
}
that.publicMethod = function () {
secret += "?"; // this method can also mess with private variables
}
that.anotherPublicVariable = "baz";
return that; // this is the object we've constructed
}
makeObject.static = "This can be used to add a static varaible/method";
var bar = makeObject();
bar.publicMethod(); // ok
alert(bar.thisIsPublic); // ok
bar.secretFunction(); // error!
bar.secret // error!
JavaScriptの関数はクロージャなので、プライベート変数とメソッドを使用して回避できnewます。
JavaScriptのプライベート変数に関するhttp://javascript.crockford.com/private.htmlから。
以下のコードは、オブジェクトを作成する3つの方法、オブジェクトリテラル構文、関数コンストラクター、およびを示していObject.create()ます。オブジェクトリテラル構文__prototype__は、その場でオブジェクトを作成するだけなので、Objectオブジェクトであり、のすべてのプロパティとメソッドにアクセスできますObject。設計パターンの観点から厳密に言うと、単純なオブジェクトリテラルを使用して、データの単一のインスタンスを格納する必要があります。
関数コンストラクタには、という名前の特別なプロパティがあり.prototypeます。このプロパティは__prototype__、関数コンストラクターによって作成されたオブジェクトのになります。.prototype関数コンストラクターのプロパティに追加されたすべてのプロパティとメソッドは、作成したすべてのオブジェクトで使用できます。データの複数のインスタンスが必要な場合、またはオブジェクトからの動作が必要な場合は、コンストラクターを使用する必要があります。関数コンストラクターは、プライベート/パブリック開発パターンをシミュレートする場合にも最適に使用されることに注意してください。すべての共有メソッドを必ずに配置して.prototype、各オブジェクトインスタンスで作成されないようにします。
でオブジェクトを作成するにObject.create()は、__prototype__このメソッドで作成されたオブジェクトのオブジェクトリテラルを利用します。オブジェクトリテラルに追加されたすべてのプロパティとメソッドは、真のプロトタイプ継承によってそこから作成されたすべてのオブジェクトで使用できます。これは私の好みの方法です。
//Object Example
//Simple Object Literal
var mySimpleObj = {
prop1 : "value",
prop2 : "value"
}
// Function Constructor
function PersonObjConstr() {
var privateProp = "this is private";
this.firstname = "John";
this.lastname = "Doe";
}
PersonObjConstr.prototype.greetFullName = function() {
return "PersonObjConstr says: Hello " + this.firstname +
" " + this.lastname;
};
// Object Literal
var personObjLit = {
firstname : "John",
lastname: "Doe",
greetFullName : function() {
return "personObjLit says: Hello " + this.firstname +
", " + this.lastname;
}
}
var newVar = mySimpleObj.prop1;
var newName = new PersonObjConstr();
var newName2 = Object.create(personObjLit);
Object.create、リテラル内の関数を使用してオブジェクトを作成すると、インスタンスごとに一意になりますか?
何をしたいかによります。オブジェクトで(半)プライベート変数または関数を使用する場合は、コンストラクター関数を使用します。オブジェクトにプロパティとメソッドのみが含まれている場合は、オブジェクトリテラルで問題ありません。
function SomeConstructor(){
var x = 5;
this.multiply5 = function(i){
return x*i;
}
}
var myObj = new SomeConstructor;
var SomeLiteral = {
multiply5: function(i){ return i*5; }
}
今の方法multiply5でmyObjとSomeLiteralまったく同じことを行います。唯一の違いは、myObjがプライベート変数を使用することです。後者はいくつかの場合に役立つかもしれません。ほとんどの場合、オブジェクトリテラルで十分であり、JSオブジェクトを作成するための優れたクリーンな方法です。
ページのオブジェクトの単一インスタンスが必要ですか-リテラル。
DTOオブジェクトのような単純なデータを転送するだけですか?GET SET:-Literal
メソッドの動作、複数のインスタンスを持つ実際のオブジェクトを作成しますか-コンストラクター関数、OOP原則に従う、継承:-コンストラクター関数。
以下は、リテラルとは何か、コンストラクタ関数とは何か、それらがどのように異なるのかを詳しく説明しているyoutubeビデオです。
オブジェクトリテラルを使用すると、初期値が導入されるため、より簡潔で拡張性が高くなります。
https://www.w3schools.com/js/js_object_definition.aspで述べたように
オブジェクトリテラルを使用すると、 1 つの ステートメントで1 つのオブジェクトを定義および作成できます。
また
オブジェクトリテラルは、単一のオブジェクトのみを作成します。1つのタイプの多くのオブジェクトを作成するために使用できるオブジェクトタイプが必要な場合があります。
Object()コンストラクター関数は少し遅く、より冗長です。そのため、JavaScriptで新しいオブジェクトを作成するための推奨される方法は、リテラル表記を使用することです
実際には、オブジェクトリテラルにプライベートメソッドを含めることができます。以下のコードを検討してください:
var myObject = {
publicMethod: function () {
privateMethod1();
privateMethod2();
function privateMethod1(){
console.log('i am privateMethod1');
}
function privateMethod2(){
console.log('i am privateMethod2');
}
}
}
好みの問題ですが、可能な場合はオブジェクトリテラルを使用することを好みます。
//オブジェクトリテラルとオブジェクトコンストラクタ
function MyData(foo, bar) {
this.foo = foo;
this.bar = bar;
}
MyData.prototype.verify = function () {
return this.foo === this.bar;
};
//add property using prototype
var MD = new MyData;//true.
var MD = new MyData();//true.
MD.verify// return only the function structure.
MD.verify(); //return the verify value and in this case return true coz both value is null.
var MD1 = new MyData(1,2); // intialized the value at the starting.
MD1.verify// return only the function structure.
MD1.verify(); // return false coz both value are not same.
MD1.verify(3,3);// return false coz this will not check this value intialized at the top
MyData.prototype.verify = function (foo,bar) {
return this.foo === this.bar;
};
var MD1 = new MyData(1,2);
MD1.verify();
MD1.verify(3,3);// return false coz this keyword used with foo and bar that will check parent data