Haruskah saya menggunakan literal objek atau fungsi konstruktor?

94

Saya bingung ke mana saya harus membuat objek di javascript. Sepertinya setidaknya ada dua cara. Salah satunya adalah dengan menggunakan notasi literal objek sedangkan yang lainnya menggunakan fungsi konstruksi. Apakah ada keuntungan yang satu dibandingkan yang lain?

chobo
sumber
1
Jawaban terbaik: stackoverflow.com/questions/4597926/… - Singkatnya, Anda juga dapat menyiapkan fungsi untuk membuat instance bentuk notasi literal. Melakukan ini setiap contoh membawa semua metode, sedangkan dengan konstruktor semua contoh mengacu pada metode prototipe. Yaitu konstruktor memiliki kinerja memori yang lebih baik.
Federico
Jika memori bukan masalah akses properti literal objek jauh lebih cepat - jsperf.com/module-pattern-vs-object-literal-vs-prototype/4
Daniel Sokolowski

Jawaban:

131

Jika Anda tidak memiliki perilaku yang terkait dengan suatu objek (yaitu jika objek tersebut hanya wadah untuk data / status), saya akan menggunakan literal objek.

var data = {
    foo: 42,
    bar: 43
};

Terapkan prinsip KISS . Jika Anda tidak memerlukan apa pun selain wadah data sederhana, gunakan literal sederhana.

Jika Anda ingin menambahkan perilaku ke objek Anda, Anda dapat menggunakan konstruktor dan menambahkan metode ke objek selama konstruksi atau memberikan prototipe kelas Anda.

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;
};

Kelas seperti ini juga bertindak seperti skema untuk objek data Anda: Anda sekarang memiliki semacam kontrak (melalui konstruktor) properti apa yang diinisialisasi / berisi objek. Literal gratis hanyalah gumpalan data yang tidak berbentuk.

Anda mungkin juga memiliki verifyfungsi eksternal yang bekerja pada objek data lama biasa:

var data = {
    foo: 42,
    bar: 43
};

function verify(data) {
    return data.foo === data.bar;
}

Namun, ini tidak menguntungkan sehubungan dengan enkapsulasi: Idealnya, semua data + perilaku yang terkait dengan suatu entitas harus hidup bersama.

Ates Goral
sumber
12
Penjelasan yang bagus, tapi bagaimana dengan menempatkan fungsi dalam sebuah objek literal? Saya telah melihat ini dilakukan sebelumnya. Sebenarnya postingan di bawah ini memiliki contohnya.
chobo
23
Jika Anda menyertakan definisi fungsi sebagai bagian dari literal objek, atau menggunakan this.fn = function ...pendekatan dalam konstruktor, setiap instance objek Anda akan memiliki salinan fungsinya sendiri. Dengan menggunakan pendekatan prototipe, Anda melampirkan setiap fungsi sekali dan hanya sekali: fungsi tersebut akan diwarisi oleh instance melalui pewarisan prototipe.
Ates Goral
14
Saya yakin Anda melewatkan satu hal penting. hanya fungsi konstruktor yang dapat menyediakan anggota pribadi serta anggota publik (enkapsulasi). dalam objek literal - semuanya publik.
Royi Namir
Apa cara yang lebih baik untuk menggunakan mesin game? Saya menggunakan metode konstruktor tetapi prototipe saya tidak memiliki akses ke data konstruktor.
zachdyer
90

Ini pada dasarnya bermuara pada apakah Anda membutuhkan banyak contoh dari objek Anda atau tidak; objek yang ditentukan dengan konstruktor memungkinkan Anda memiliki beberapa contoh objek itu. Literal objek pada dasarnya adalah lajang dengan variabel / metode yang semuanya bersifat publik.

// 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
ronnbot
sumber
1
Ini adalah poin yang sangat bagus untuk diingat saat memutuskan. Terima kasih.
zkent
Menurut pengalaman saya, inilah yang membuat perbedaan. Contoh jelas yang bagus.
Air
9

Cara lain untuk membuat objek dengan cara yang seragam adalah dengan menggunakan fungsi yang mengembalikan objek:

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!

Karena fungsi dalam JavaScript adalah closure, kita dapat menggunakan variabel dan metode privat dan menghindarinya new.

Dari http://javascript.crockford.com/private.html tentang variabel pribadi di JavaScript.

JustcallmeDrago
sumber
7

Kode di bawah ini menunjukkan tiga metode membuat objek, sintaks Objek Literal, Pembuat Fungsi dan Object.create(). Sintaks literal objek hanya membuat dan objek dengan cepat dan dengan demikian itu __prototype__adalah Objectobjek dan itu akan memiliki akses ke semua properti dan metodeObject . Ketat dari perspektif pola desain, literal Objek sederhana harus digunakan untuk menyimpan satu contoh data.

Konstruktor fungsi memiliki properti khusus bernama .prototype. Properti ini akan menjadi __prototype__salah satu objek yang dibuat oleh konstruktor fungsi. Semua properti dan metode yang ditambahkan ke .prototypeproperti konstruktor fungsi akan tersedia untuk semua objek yang dibuatnya. Konstruktor harus digunakan jika Anda memerlukan beberapa contoh data atau memerlukan perilaku dari objek Anda. Perhatikan bahwa konstruktor fungsi juga paling baik digunakan saat Anda ingin mensimulasikan pola pengembangan pribadi / publik. Ingatlah untuk meletakkan semua metode bersama pada .prototypesehingga mereka tidak akan dibuat di setiap contoh objek.

Membuat objek dengan Object.create()memanfaatkan literal objek sebagai __prototype__objek yang dibuat dengan metode ini. Semua properti dan metode yang ditambahkan ke literal objek akan tersedia untuk semua objek yang dibuat darinya melalui pewarisan prototipe yang sebenarnya. Ini adalah metode pilihan saya.

//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);
JOP
sumber
1
Karena Anda mendeklarasikan fungsi di dalam literal objek. Apakah itu berarti ketika Anda membuat objek menggunakan Object.createfungsi di dalam literal akan menjadi unik per instance?
JohnnyQ
6

Itu tergantung pada apa yang ingin Anda lakukan. Jika Anda ingin menggunakan variabel atau fungsi privat (semi-) di objek Anda, fungsi konstruktor adalah cara untuk melakukannya. Jika objek Anda hanya berisi properti dan metode, literal objek tidak masalah.

function SomeConstructor(){
    var x = 5;
    this.multiply5 = function(i){
        return x*i;
    }
}
var myObj = new SomeConstructor;

var SomeLiteral = {
    multiply5: function(i){ return i*5; }
}

Sekarang metode multiply5masuk myObjdan SomeLiterallakukan hal yang persis sama. Satu-satunya perbedaan adalah myObj menggunakan variabel privat. Yang terakhir mungkin berguna dalam beberapa kasus. Seringkali sebuah literal Objek cukup dan cara yang bagus dan bersih untuk membuat objek JS.

KooiInc
sumber
Apa perbedaan antara fungsi dan metode? Saya berasal dari latar belakang ac # jadi bagi saya suatu fungsi adalah mandiri dan metode hanyalah fungsi yang merupakan bagian dari kelas.
chobo
1
Tidak banyak perbedaannya, lihat misalnya web-source.net/javascript_tutorial/… . Sebenarnya, dalam DOMscripting (sisi klien js di browser), semua fungsi menjadi metode objek jendela (namespace global) menurut saya (Anda dapat menangani semua fungsi 'mandiri' sebagai jendela. [Beberapa fungsi].
KooiInc
5

masukkan deskripsi gambar di sini

Apakah Anda ingin satu contoh objek untuk halaman - Literal.

Apakah Anda ingin mentransfer data seperti objek DTO sederhana GET SET: - Literal

Apakah Anda ingin membuat objek nyata dengan perilaku metode, beberapa contoh - Fungsi pembuat, Ikuti prinsip OOP, pewarisan: - Fungsi pembuat.

Di bawah ini adalah video youtube yang menjelaskan secara rinci apa itu literal, apa itu fungsi konstruktor dan bagaimana perbedaannya satu sama lain.

https://www.youtube.com/watch?v=dVoAq2D3n44

Shivprasad Koirala
sumber
1

Gunakan literal objek, itu lebih padat dan berkembang lebih baik dengan pengenalan nilai awal.

Tom
sumber
Bagaimana Anda membuat variabel privat dalam literal objek?
EhevuTov
Anda tidak bisa, itu tidak relevan dengan pertanyaan asli jadi saya hanya akan memberi Anda tautan: javascript.crockford.com/private.html
Tom
1
Sebenarnya, ini relevan karena jika ada perbedaan, ada alasan untuk menggunakan salah satunya tergantung pada situasi tertentu; dalam contoh ini apakah Anda menginginkan variabel privat atau tidak. Anda dapat membuat variabel privat secara literal dengan terlebih dahulu membuat fungsi penutupan dalam literal Anda, tetapi menurut saya jauh lebih jelek dan sulit dibaca.
EhevuTov
Saya berdiri dikoreksi, pembacaan asli saya dari pertanyaan itu adalah bahwa chobo bertanya tentang cara meneruskan variabel ke konstruktor seperti dalam daftar parameter vs parameter literal objek tunggal.
Tom
1

Seperti disebutkan di https://www.w3schools.com/js/js_object_definition.asp

Menggunakan literal objek, Anda berdua mendefinisikan dan membuat , satu objek dalam satu pernyataan.

Juga

Objek literal hanya membuat satu objek. Terkadang kami ingin memiliki tipe objek yang dapat digunakan untuk membuat banyak objek dari satu tipe.

Alireza Fattahi
sumber
0

Fungsi konstruktor Object () sedikit lebih lambat dan lebih bertele-tele. Karena itu, cara yang disarankan untuk membuat objek baru di JavaScript adalah dengan menggunakan notasi literal

JavaScript Berorientasi Objek Udacity

techkuz
sumber
0

Sebenarnya, methinks, kita dapat memiliki metode privat dalam literal objek. Pertimbangkan kode di bawah ini:

var myObject = {

   publicMethod: function () {
      privateMethod1();
      privateMethod2(); 
      function privateMethod1(){
          console.log('i am privateMethod1');
      } 
      function privateMethod2(){
          console.log('i am privateMethod2');
      } 
   }

}

Soal selera, tapi saya lebih suka menggunakan literal objek jika memungkinkan.

yurin
sumber
-1

// Objek literal dan konstruktor objek

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 
Amit kumar
sumber
1
Di mana dalam contoh Anda literal Objek dideklarasikan?
JohnnyQ