Koks skirtumas tarp naujos „Object“ () ir objekto literatūros versijos?

Koks skirtumas tarp šios sintaksės, pagrįstos konstruktoriumi kuriant objektą:

 person = new Object() 

... ir ši pažodinė sintaksė:

 person = { property1 : "Hello" }; 

Atrodo, kad abi tos pačios daro, nors JSLint nori naudoti objektinę literatūrą.

Kuris iš jų yra geresnis ir kodėl?

159
04 янв. nustatė ectype sausio 04 d 2011-01-04 23:09 '11 11:09 PM 2011-01-04 23:09
@ 9 atsakymai

Jie abu daro tą patį (nebent kas nors daro kažką neįprasto), išskyrus tai, kad jūsų antrasis sukuria objektą ir prideda turtą. Tačiau pažodinis žymėjimas užima mažiau vietos šaltinio kode. Ji aiškiai atpažįsta, kas vyksta, todėl naudojant new Object() jūs tiesiog įvesite daugiau ir (teoriškai, jei „JavaScript“ variklis nėra optimizuotas), atlikite nereikalingą funkcijų skambutį.

Tai yra

 person = new Object()  -or- person = { property1 : "Hello" }; 

techniškai to nedaro. Pirmasis tiesiog sukuria objektą. Antrasis sukuria ir priskiria turtą. Kad pirmasis būtų tas pats, jums reikės antrojo žingsnio, kad sukurtumėte ir priskirtumėte turtą.

„Kažkas neįprastas“, kurį kažkas galėtų padaryti, būtų šešėlis arba priskirtų Object visuotinai pagal nutylėjimą:

 // Don't do this Object = 23; 

Šiuo itin neįprastu atveju new Object nepavyks, bet {} veiks.

Praktiškai niekada nebuvo priežasčių naudoti new Object , o ne {} (nebent tai padarėte labai neįprasta).

96
04 янв. atsakymą pateikė kemiller2002 04 sausis 2011-01-04 23:10 '11, 11:10 pm 2011-01-04 23:10

Nėra skirtumo paprastam objektui be metodų, kaip jūsų pavyzdyje. Tačiau yra didelis skirtumas, kai pradedate pridėti metodus prie savo objekto.

Literatūrinis būdas:

 function Obj( prop ) { return { p : prop, sayHello : function(){ alert(this.p); }, }; } 

Prototipas:

border=0
 function Obj( prop ) { this.p = prop; } Obj.prototype.sayHello = function(){alert(this.p);}; 

Abu metodai leidžia sukurti „ Obj atvejus taip:

 var foo = new Obj( "hello" ); 

Tačiau, pažodžiui, kiekviename savo objektų egzemplioriuje yra „ sayHello metodo kopija. Su prototipu metodas apibrėžtas objekto prototipe ir paskirstomas visiems objekto egzemplioriams. Jei turite daug objektų ar daug metodų, tada pažodinis kelias gali sukelti gana didelius atminties nuostolius.

203
29 авг. atsakymą pateikė Rémy DAVID 29 rug. 2012-08-29 13:04 '12 13:04 2012-08-29 13:04

„JavaScript“ galime paskelbti naują tuščią objektą dviem būdais:

 var obj1 = new Object(); var obj2 = {}; 

Aš neradau nieko, kas leistų manyti, kad yra du reikšmingi skirtumai, kaip jie veikia užkulisiuose (prašau ištaisyti, jei aš klystu - norėčiau sužinoti). Tačiau antrasis metodas (naudojant objektų žymėjimą) siūlo keletą privalumų.

  • Trumpai (tiksliau - 10 simbolių)
  • Lengviau ir struktūrizuotiau kurti objektus skristi.
  • Nesvarbu, ar bet kuris šaulys netyčia nepaiso objekto

Apsvarstykite naują objektą, kuriame yra elementai Name ir TelNo. Naudodami naują Objekto () konvenciją, galime ją sukurti taip:

 var obj1 = new Object(); obj1.Name = "A Person"; obj1.TelNo = "12345"; 

Expando Properties“ „ JavaScript“ funkcija leidžia mums sukurti naujus narius tokiu būdu, ir mes pasiekiame tai, ką norėjome. Tačiau šis metodas nėra labai struktūrizuotas arba kapsulinis. Ką daryti, jei norime sukurti dalyvius juos kuriant, nesiremdami išplėtimo savybėmis ir po kūrimo užduotimi?

Čia galite naudoti objekto dokumentinį filmą:

 var obj1 = {Name:"A Person",TelNo="12345"}; 

Čia pasiekėme tą patį efektą vienoje kodo eilutėje ir žymiai mažiau simbolių.

Toliau aptariami pirmiau aprašyti objekto konstrukcijos metodai: „ JavaScript“ ir „Object Oriented Programming“ (OOP).

Ir, galiausiai, koks idiotas apsimetė objektą? Jūs manėte, kad tai neįmanoma? Na, tai JSFiddle įrodo priešingą. Objekto literatūros žymėjimo naudojimas neleidžia mums nukristi nuo šio slapto rakto.

(Nuo http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/ )

49
01 апр. James Wiseman atsakymas, pateiktas balandžio 01 d 2011-04-01 15:30 '11 15:30 val. 2011-04-01 15:30

Mano kompiuteryje naudojant „Node.js“ paleidžiau:

 console.log('Testing Array:'); console.time('using[]'); for(var i=0; i<200000000; i++){var arr = []}; console.timeEnd('using[]'); console.time('using new'); for(var i=0; i<200000000; i++){var arr = new Array}; console.timeEnd('using new'); console.log('Testing Object:'); console.time('using{}'); for(var i=0; i<200000000; i++){var obj = {}}; console.timeEnd('using{}'); console.time('using new'); for(var i=0; i<200000000; i++){var obj = new Object}; console.timeEnd('using new'); 

Atkreipkite dėmesį, kad tai yra papildymas, kas yra čia: Kodėl arr = [] greičiau nei arr = new array?

Mano rezultatas buvo toks:

 Testing Array: using[]: 1091ms using new: 2286ms Testing Object: using{}: 870ms using new: 5637ms 

taip aiškus {} ir [] yra greitesnis nei naudojant naują, kad sukurtumėte tuščius objektus / matricas.

33
29 янв. atsakymą rjloura pateikė sausio mėn . 2014-01-29 18:56 '14 at 18:56 2014-01-29 18:56

Visi čia kalba apie šių dviejų panašumų. Noriu atkreipti dėmesį į skirtumus.

  • Naudojant new Object() galite pereiti kitą objektą. Akivaizdu, kad naujai sukurtas objektas bus nustatytas į tą pačią nuorodą. Štai pavyzdinis kodas:

     var obj1 = new Object(); obj1.a = 1; var obj2 = new Object(obj1); obj2.a // 1 
  • Naudojimas neapsiriboja objektais, kaip ir OOP objektuose. Kiti tipai taip pat gali būti perduoti jam. Funkcija atitinkamai nustatys tipą. Pavyzdžiui, jei perduosime jį 1 sveiką skaičių, mums bus sukurtas numerio tipo objektas.

     var obj = new Object(1); typeof obj // "number" 
  • Objektas, sukurtas naudojant pirmiau nurodytą metodą ( new Object(1) ), bus konvertuojamas į objekto tipą, jei prie jo pridedama nuosavybė.

     var obj = new Object(1); typeof obj // "number" obj.a = 2; typeof obj // "object" 
  • Jei objektas yra objekto vaiko klasės kopija, mes galime pridėti savybę be tipo konvertavimo.

     var obj = new Object("foo"); typeof obj // "object" obj === "foo" // true obj.a = 1; obj === "foo" // true obj.a // 1 var str = "foo"; str.a = 1; str.a // undefined 
25
14 дек. Atsakymą pateikė Jermin Bazazian 14 dec. 2012-12-14 09:55 '12 at 9:55 2012-12-14 09:55

Iš tikrųjų, yra keli būdai, kaip sukurti „JavaScript“ objektus. Kai tik norite sukurti objektą, nėra prasmės kurti objektus pagal konstruktorių, naudojant naują operatorių. Tas pats, kaip objekto kūrimas naudojant objektyvią sintaksę. Bet " konstruktyvūs objektai, sukurti naudojant" naują ", yra neįtikėtinai naudingi, kai galvojate apie" prototipinį paveldėjimą " „Negalite išlaikyti paveldėjimo grandinės su objektais, sukurtais naudojant pažodinę sintaksę. Bet jūs galite sukurti konstruktorių , savo prototipui prijunkite savybes ir metodus. Tada, priskyrus šį konstruktoriaus funkciją bet kuriam kintamajam naudojant naują operatorių, jis grąžins objektą, kuris turės prieigą prie visų metodų ir savybių, susijusių su šio konstruktoriaus funkcijos prototipu.

Štai pavyzdys, kaip sukurti objektą naudojant konstruktoriaus funkciją (žr. Toliau pateikto kodo paaiškinimą):

 function Person(firstname, lastname) { this.firstname = firstname; this.lastname = lastname; } Person.prototype.fullname = function() { console.log(this.firstname + ' ' + this.lastname); } var zubaer = new Person('Zubaer', 'Ahammed'); var john = new Person('John', 'Doe'); zubaer.fullname(); john.fullname(); 

Dabar galite sukurti tiek objektų, kiek norite, kurdami Asmens kūrimo funkciją, ir jie visi paveldi pilną vardą ().

Pastaba: šis raktinis žodis bus susijęs su tuščiu objektu, esančiu konstruktoriaus funkcijoje, ir kai kuriate naują objektą iš asmens, kuris naudoja naują operatorių, jis automatiškai grąžina objektą, kuriame yra visos su šiuo raktiniu žodžiu susijusios savybės ir metodai. Ir šis objektas tikriausiai paveldi su prototipu susijusius metodus ir savybes. Asmens konstruktoriaus funkcijos (tai yra pagrindinis šio požiūrio privalumas).

Beje, jei norite gauti tą patį funkcionalumą su objekto gramatine sintakse, jums reikės sukurti pilną vardą () visiems objektams, kaip parodyta žemiau:
 var zubaer = { firstname: 'Zubaer', lastname: 'Ahammed', fullname: function() { console.log(this.firstname + ' ' + this.lastname); } }; var john= { firstname: 'John', lastname: 'Doe', fullname: function() { console.log(this.firstname + ' ' + this.lastname); } }; zubaer.fullname(); john.fullname(); 

Galiausiai, jei jūs dabar paklausiate, kodėl turėčiau naudoti konstruktoriaus požiūrį vietoj objektyvo :

*** Prototipo paveldėjimas leidžia paprastą paveldėjimo grandinę, kuri gali būti labai naudinga ir galinga.

*** Tai taupo atmintį, paveldi bendrus metodus ir savybes, apibrėžtas konstruktoriaus funkcijų prototipe. Priešingu atveju visuose objektuose turėsite juos kopijuoti dar kartą.

Tikiuosi, kad tai prasminga.

12
Atsakymas pateikiamas Md. 02 авг. Zubaer Ahammed rugpjūčio 02 2016-08-02 17:55 '16 at 17:55 pm 2016-08-02 17:55

Be to, pagal kai kurias „Javascript O'Really ....“ knygas (cituota)

Kita literatūros naudojimo priežastis, priešingai nei Objekto konstruktorius, yra tai, kad regiono išsprendimas neegzistuoja. Kadangi yra įmanoma, kad sukūrėte vietinį konstruktorių, turintį tokį patį pavadinimą, vertėjas turi ieškoti taikymo srities grandinės iš vietos, kur skambinate Objektui (), kol rasite pasaulinį objektų konstruktorių.

8
22 февр. atsakymas duotas adolfo_isassi 22 vasaris 2013-02-22 21:25 '13, 21:25, 2013-02-22 21:25

Radau vieną ES6 / ES2015 skirtumą. Negalite grąžinti objekto naudodami rodyklių nuorodos funkcijos sintaksę, nebent objektą supa new Object() .

 > [1, 2, 3].map(v => {n: v}); [ undefined, undefined, undefined ] > [1, 2, 3].map(v => new Object({n: v})); [ { n: 1 }, { n: 2 }, { n: 3 } ] 

Taip yra dėl to, kad kompiliatorių painioja skliausteliuose {} ir mano, kad n: i yra etiketė: pareiškimo konstrukcija; kabliataškis yra neprivalomas, todėl ji nesiskundžia.

Jei prie objekto pridedate kitą savybę, jis pagaliau pateikia klaidą.

 $ node -e "[1, 2, 3].map(v => {n: v, m: v+1});" [1, 2, 3].map(v => {n: v, m: v+1}); ^ SyntaxError: Unexpected token : 
2
14 апр. Andrei Simionescu atsakymas, pateiktas balandžio 14 d 2016-04-14 19:56 '16 at 7:56 pm 2016-04-14 19:56

Atminties naudojimas skiriasi, jei sukuriate 10 tūkst. Kopijų. new Object() bus tik viena kopija ir {} bus saugoma 10 tūkst. kopijų.

-2
13 июня '16 в 12:23 2016-06-13 12:23 Atsakymas, kurį pateikė Richard Miao US birželio 13–16 d., 12:23 2016-06-13 12:23

Kiti klausimai apie „ žymas „ arba „ Užduoti klausimą“