อะไรคือความแตกต่างระหว่าง `วัตถุใหม่ () 'กับสัญกรณ์ตามตัวอักษร?


199

อะไรคือความแตกต่างระหว่างไวยากรณ์ที่สร้างขึ้นนี้สำหรับการสร้างวัตถุ:

person = new Object()

... และไวยากรณ์ตามตัวอักษรนี้:

person = {
    property1 : "Hello"
};

ปรากฏว่าทั้งคู่ทำสิ่งเดียวกันแม้ว่า JSLint จะชอบให้คุณใช้สัญกรณ์ตามตัวอักษร

อันไหนดีกว่าและทำไม?


7
ทั้งหมดเดียวกัน: a = new Object, a = new Object(), a = {}, อักษรง่ายมากและการทดสอบบางอย่างที่ฉันวิ่งในขณะที่ที่ผ่านมาบอกว่ามันจะเร็วขึ้นคอมไพเลอร์รุ่นใหม่อาจจะเกิดจากคำสั่งของฉันเป็นเท็จ เช่นเดียวกันกับอาร์เรย์ตามตัวอักษร
Juan Mendes

8
หวังว่าคุณจะประกาศตัวแปรของคุณด้วยvarคำสำคัญในรหัสแอปพลิเคชันของคุณเพื่อหลีกเลี่ยงการสร้างมลภาวะเนมสเปซส่วนกลางและสร้างความจำเป็นที่จะต้องดูมากกว่าระเบียนปัจจุบันในสแต็กสำหรับตัวแปรของคุณ
Samo

1
โดยพื้นฐาน ณ จุดใด ๆ ในระหว่างการดำเนินการของโปรแกรมจะมีสแต็คของบันทึกหรือบล็อก แต่ละเรคคอร์ดมีรายการตัวแปรที่สร้างขึ้นในขอบเขตนั้น ใน JavaScript หากนิพจน์มีตัวแปรและล่ามไม่สามารถหามันในสแต็กเร็กคอร์ดสำหรับขอบเขตนั้นมันจะขึ้นไปยังระเบียนถัดไปจนกว่าจะพบตัวแปร ข้อมูลเพิ่มเติมdavidshariff.com/blog/…
Samo

2
การหลีกเลี่ยง JSLint เป็นขั้นตอนแรกในการเป็นนักพัฒนาที่ดี การใช้newเป็นแบบแผนที่เหนือกว่า nitpicking ไม่มีจุดหมายของภาษาปานกลาง ใช้newเพราะความหมายของมันชัดเจน ใน 99.9% ของเคสประสิทธิภาพที่เพิ่มขึ้นนั้นไม่เกี่ยวข้อง
Hal50000

1
@ Hal50000 ภาษาปานกลางตามใคร?
Xam

คำตอบ:


124

พวกเขาทั้งสองทำสิ่งเดียวกัน (ยกเว้นบางคนทำสิ่งที่ผิดปกติ) นอกเหนือจากที่สองของคุณสร้างวัตถุและเพิ่มคุณสมบัติให้กับมัน แต่สัญกรณ์ที่แท้จริงนั้นใช้พื้นที่น้อยในซอร์สโค้ด มันเป็นที่รู้จักอย่างชัดเจนว่าเกิดอะไรขึ้นดังนั้นเมื่อใช้new Object()คุณพิมพ์ได้มากขึ้นและในทางทฤษฎีหากไม่ได้รับการปรับแต่งโดยเอนจิ้น JavaScript ให้ทำการเรียกฟังก์ชั่นที่ไม่จำเป็น

เหล่านี้

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

ในทางเทคนิคไม่ได้ทำสิ่งเดียวกัน ครั้งแรกที่เพิ่งสร้างวัตถุ ที่สองสร้างหนึ่งและกำหนดคุณสมบัติ เพื่อให้คนแรกเหมือนกันคุณต้องมีขั้นตอนที่สองเพื่อสร้างและกำหนดคุณสมบัติ

"บางสิ่งบางอย่างที่ผิดปกติ" ที่ใครบางคนสามารถทำได้คือการทำเงาหรือกำหนดให้กับค่าเริ่มต้นของObjectโลก:

// Don't do this
Object = 23;

ในกรณีที่ผิดปกติอย่างมากnew Objectจะล้มเหลว แต่{}จะทำงาน

ในทางปฏิบัติไม่มีเหตุผลที่จะใช้new Objectมากกว่า{}(เว้นแต่คุณจะทำสิ่งที่ผิดปกติมาก)


11
ผู้เขียนเลือกคำตอบนี้ว่าถูกต้อง แต่ไม่สมบูรณ์ ระวังว่ามีความแตกต่างระหว่างสองไวยากรณ์เมื่อคุณเข้าสู่การจัดสรรหน่วยความจำ
newshorts

2
ไม่มีความแตกต่าง หากคุณอ้างถึงคำตอบอย่างใดอย่างหนึ่งภายใต้มันเป็นหัวข้อนอกขณะที่มันพูดคุยเกี่ยวกับรูปแบบวัตถุต้นแบบและการสืบทอด (รหัสมีการตั้งค่าคลาส Obj ที่สืบทอดจากวัตถุธรรมดา) คำถามนี้ไม่ได้เกี่ยวกับการสร้างอินสแตนซ์ของคลาสที่กำหนดเอง แต่เกี่ยวกับการสร้างอินสแตนซ์ของ Object และคำตอบที่ถูกต้องสำหรับคำถามนี้คือ "ไม่มีความแตกต่าง"
dos

() new Object()ไม่จำเป็นต้องใช้FYI (พูดคุยเกี่ยวกับสิ่งที่ไม่จำเป็นต้องใช้)
Royi Namir

ฉันคิดว่าเราไม่จำเป็นต้องใช้สิ่งใหม่ตามข้อกำหนดปัจจุบัน แจ้งให้เราทราบความคิดของคุณ @kevin
Vamsi Pavan Mahesh

1
คุณยังสามารถใช้ Object create และ pass null ได้หากคุณต้องการให้อ็อบเจกต์ที่ไม่ได้รับสืบทอดจากเชนการสืบทอด มันไม่เท่ากันและมีประโยชน์ตามลำดับ
แอรอน

234

ไม่มีความแตกต่างสำหรับวัตถุอย่างง่ายโดยไม่มีวิธีการในตัวอย่างของคุณ อย่างไรก็ตามมีความแตกต่างใหญ่เมื่อคุณเริ่มเพิ่มวิธีการในวัตถุของคุณ

ทางอักษร:

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

วิธีต้นแบบ:

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

ทั้งสองวิธีอนุญาตให้สร้างอินสแตนซ์Objเช่นนี้:

var foo = new Obj( "hello" ); 

อย่างไรก็ตามด้วยวิธีการตามตัวอักษรคุณจะต้องนำสำเนาของsayHelloวิธีการภายในแต่ละวัตถุของคุณ ในขณะที่ด้วยวิธีต้นแบบวิธีการที่กำหนดไว้ในต้นแบบวัตถุและใช้ร่วมกันระหว่างวัตถุทุกอินสแตนซ์ หากคุณมีวัตถุจำนวนมากหรือมีวิธีการมากมายวิธีการตามตัวอักษรอาจทำให้เสียความทรงจำที่ค่อนข้างใหญ่


39
สำหรับฉันแล้วคำถามเกี่ยวกับความแตกต่างระหว่างการใช้new Object()vs {}เพื่อสร้างวัตถุเปล่า
ปีเตอร์

11
@Lababob นอกเหนือจากประโยคแรกคำตอบนี้ไม่ได้ให้ข้อมูลใด ๆ เกี่ยวกับคำถามของ OP มันไม่ได้มี 'วัตถุใหม่ () `ทุกที่ ตรงไปตรงมาฉันคิดว่านายเดวิดเข้าใจผิดคำถาม
JLRishe

17
เมื่อฉันโพสต์ข้อความนี้คำตอบที่ยอมรับมีอยู่แล้วและตอบรับแล้ว และมันก็ตอบคำถาม OP ได้อย่างสมบูรณ์แบบดังนั้นฉันจะไม่ทำซ้ำในสิ่งเดียวกัน ฉันโพสต์คำตอบของฉันเป็นหลักเพื่อขยายเรื่องเกินวัตถุที่ว่างเปล่า / ง่าย ซึ่งในกรณีที่มีคือความแตกต่างที่สำคัญที่มีมูลค่าการกล่าวขวัญ
Rémy DAVID

3
คำตอบนี้อยู่นอกหัวข้อ ในรหัสของคุณ Obj เป็นคลาสที่แยกจากการสืบทอดวัตถุ เมื่อคุณใช้สัญกรณ์ตัวอักษรคุณใช้คลาส Object ไม่ใช่ Obj แน่นอนว่าการตั้งค่าคลาสด้วยวิธีการในต้นแบบนั้นจะทำให้ขนาดหน่วยความจำเล็กกว่าการสร้างออบเจ็กต์ธรรมดาจำนวนมากและวิธีการเพิ่มเป็นคุณสมบัติของพวกเขา แต่นั่นไม่เกี่ยวข้องกับคำถามที่ถามอย่างสมบูรณ์ คำตอบที่ถูกต้องสำหรับคำถามนี้คือ "ไม่ไม่มีความแตกต่างอย่างแน่นอน (อาจยกเว้นการอ่านได้)"
dos

3
ฉันมาเพื่อคำตอบนี้ตามคำถามที่เหมือนฉัน แต่จบลงด้วยการเรียนรู้สิ่งที่ฉันต้องการรู้ ขอบคุณ.
Pat Migliaccio

55

ใน JavaScript เราสามารถประกาศวัตถุว่างใหม่ได้สองวิธี:

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

ฉันไม่พบอะไรเลยที่จะชี้ให้เห็นว่ามีความแตกต่างอย่างมีนัยสำคัญเกี่ยวกับวิธีการทำงานของเบื้องหลัง (โปรดแก้ไขให้ฉันถ้าฉันผิด - ฉันชอบที่จะรู้) อย่างไรก็ตามวิธีที่สอง (ใช้สัญกรณ์ตัวอักษร) มีข้อได้เปรียบเล็กน้อย

  1. มันสั้นกว่า (10 ตัวอักษรเพื่อความแม่นยำ)
  2. มันง่ายขึ้นและมีโครงสร้างมากขึ้นในการสร้างวัตถุได้ทันที
  3. มันไม่สำคัญว่าบัฟฟี่บางตัวจะมีออบเจกต์แทนที่โดยไม่ตั้งใจ

พิจารณาวัตถุใหม่ที่มีชื่อสมาชิกและ TelNo โดยใช้การประชุม Object () ใหม่เราสามารถสร้างมันได้เช่นนี้:

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

Expando คุณสมบัติคุณสมบัติของ JavaScript ช่วยให้เราสร้างสมาชิกใหม่ด้วยวิธีนี้ในการบินและเราบรรลุสิ่งที่ตั้งใจ อย่างไรก็ตามวิธีนี้ไม่ได้มีโครงสร้างหรือห่อหุ้มมากนัก จะเป็นอย่างไรถ้าเราต้องการระบุสมาชิกเมื่อมีการสร้างโดยไม่ต้องพึ่งพาคุณสมบัติของ expando และการสร้างโพสต์ที่ได้รับมอบหมาย

นี่คือที่สัญกรณ์ตัวอักษรของวัตถุสามารถช่วย:

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

ที่นี่เราได้รับเอฟเฟกต์เดียวกันในโค้ดหนึ่งบรรทัดและมีอักขระน้อยลงอย่างมาก

การอภิปรายเพิ่มเติมเกี่ยวกับวิธีการสร้างวัตถุด้านบนสามารถดูได้ที่: JavaScript และ Object Oriented Programming (OOP)

และในที่สุดสิ่งที่งี่เง่าที่เอาชนะวัตถุ? คุณคิดว่ามันเป็นไปไม่ได้เหรอ? ดีJSFiddle นี้พิสูจน์เป็นอย่างอื่น การใช้สัญกรณ์สัญลักษณวัตถุทำให้เราไม่สามารถทำสิ่งสกปรกได้ง่าย

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


1
วิธีการเกี่ยวกับวัตถุสร้าง ดู: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

หากคุณจะชอบวัตถุตัวอักษรมากกว่าnew Object()เพราะมีความเป็นไปได้ที่บางสิ่งบางอย่างเขียนทับฟังก์ชั่นวัตถุคุณควรจะเขียนผู้คุมทั่วสถานที่เมื่อคุณใช้ผู้ช่วยเหลือเช่นObject.keysเพื่อให้แน่ใจว่ามันไม่ได้นิยามไว้ซึ่งไร้เหตุผล ฉันมักจะแนะนำให้ผู้คนใช้สัญกรณ์ตามตัวอักษรเสมอ แต่ฉันคิดว่าข้อโต้แย้งนี้แยกออกจากกันเมื่อคุณคิดถึงผลที่ตามมาของการคิดแบบนั้น
philraj

41

บนเครื่องของฉันโดยใช้ Node.js ฉันรันสิ่งต่อไปนี้:

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');

หมายเหตุนี่เป็นส่วนขยายของสิ่งที่พบที่นี่: ทำไม arr = [] เร็วกว่า arr = new Array

ผลลัพธ์ของฉันคือต่อไปนี้:

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

ชัดเจน {} และ [] นั้นเร็วกว่าการใช้สิ่งใหม่ในการสร้างวัตถุ / อาร์เรย์ที่ว่างเปล่า


3
ฉันรู้สึกว่านี่คือคำตอบที่คำถามนั้นกำลังมองหาจริงๆแม้ว่าฉันต้องการที่จะเห็นการทดสอบเพิ่มเติมนี้บนวัตถุที่มีคุณสมบัติบางอย่างเพื่อให้แน่ใจ
Chase Sandmann

2
ตัวเลขที่น่าสนใจ มีคนที่ต้องระวังสิ่งนี้ แต่ฉันเอาออกไปว่าการจัดสรรแม้กระทั่งวัตถุที่น้อยกว่า 200,000 วัตถุจะต้องเสียค่าใช้จ่ายฉันเพียง 5.6ms ดังนั้นฉันจึงไม่ต้องกังวลเกี่ยวกับเรื่องนี้

บนโหนด 10.13.0 สิ่งที่มีการเปลี่ยนอาร์เรย์การทดสอบ: ใช้ []: 117.178ms ใช้ใหม่: 116.947ms วัตถุทดสอบ: ใช้ {}: 116.252ms ใช้ใหม่: 115.910ms
PirateApp

31

ทุกคนที่นี่กำลังพูดถึงความคล้ายคลึงกันของทั้งสอง ฉันจะชี้ให้เห็นความแตกต่าง

  1. การใช้new Object()ช่วยให้คุณผ่านวัตถุอื่น ผลลัพธ์ที่ชัดเจนคือวัตถุที่สร้างขึ้นใหม่จะถูกตั้งค่าเป็นการอ้างอิงเดียวกัน นี่คือตัวอย่างรหัส:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
  2. การใช้งานไม่ จำกัด เฉพาะวัตถุเช่นเดียวกับในวัตถุ OOP ประเภทอื่นสามารถส่งผ่านไปได้เช่นกัน ฟังก์ชั่นจะตั้งค่าประเภทตาม ตัวอย่างเช่นถ้าเราส่งจำนวนเต็ม 1 ไปยังวัตถุชนิดของหมายเลขจะถูกสร้างขึ้นสำหรับเรา

    var obj = new Object(1);
    typeof obj // "number"
  3. วัตถุที่สร้างขึ้นโดยใช้วิธีการด้านบน ( new Object(1)) จะถูกแปลงเป็นประเภทวัตถุหากมีการเพิ่มคุณสมบัติเข้าไป

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
  4. หากวัตถุนั้นเป็นสำเนาของคลาสลูกของวัตถุเราสามารถเพิ่มคุณสมบัติโดยไม่ต้องแปลงประเภท

    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

3
ฉันสับสนมากเกี่ยวกับสองบรรทัดสุดท้าย .. ทำไมถ้าคุณกำหนดให้ str.a ค่า 1 str.a นั้นไม่ได้กำหนด? @Jermin Bazazin
Andrea Scarafoni

3
@AndreaScarafoni เนื่องจากstrเป็นประเภทstringดังนั้นคุณจึงไม่สามารถกำหนดคุณสมบัติให้กับมันได้ jsfiddle.net/grq6hdx7/1
Chris Bier

1
คำตอบของ 4 เปลี่ยนไปไหม? ฉันเข้าใจผิดไม่จริงใน Chrome 53 ล่าสุด var obj = new Object("foo"); typeof obj; obj === "foo" // true
วิลเลียมฮิลตัน

21

จริงๆแล้วมีหลายวิธีในการสร้างวัตถุใน JavaScript เมื่อคุณต้องการสร้างวัตถุไม่มีประโยชน์ในการสร้างวัตถุที่ใช้ "คอนสตรัคเตอร์ " โดยใช้ตัวดำเนินการ " ใหม่ " มันเหมือนกับการสร้างวัตถุโดยใช้ไวยากรณ์" object literal " แต่วัตถุ "ที่ยึดตามคอนสตรัคเตอร์ " ที่สร้างขึ้นด้วยตัวดำเนินการ " ใหม่ " มาถึงการใช้งานอย่างไม่น่าเชื่อเมื่อคุณกำลังคิดเกี่ยวกับ "การสืบทอดต้นแบบ " คุณไม่สามารถรักษาห่วงโซ่การสืบทอดด้วยวัตถุที่สร้างขึ้นด้วยไวยากรณ์ที่แท้จริง แต่คุณสามารถสร้างฟังก์ชั่นคอนสตรัค , แนบคุณสมบัติและวิธีการกับต้นแบบของมัน"โอเปอเรเตอร์มันจะคืนค่าออบเจกต์ซึ่งจะสามารถเข้าถึงเมธอดและคุณสมบัติทั้งหมดที่แนบมากับต้นแบบของฟังก์ชันคอนสตรัคเตอร์นั้น

นี่คือตัวอย่างของการสร้างวัตถุโดยใช้ฟังก์ชั่นตัวสร้าง (ดูคำอธิบายรหัสที่ด้านล่าง):

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();

ตอนนี้คุณสามารถสร้างวัตถุได้มากเท่าที่คุณต้องการโดยการสร้างฟังก์ชั่นการสร้างคนทันทีและวัตถุทั้งหมดจะสืบทอดชื่อเต็ม () จากมัน

หมายเหตุ: " นี้ " คำหลักจะอ้างถึงวัตถุที่ว่างเปล่าภายในฟังก์ชั่นคอนสตรัคและเมื่อใดก็ตามที่คุณสร้างวัตถุใหม่จากคนใช้ " ใหม่ " ผู้ประกอบการก็จะกลับวัตถุที่มีทั้งหมดของคุณสมบัติและวิธีการที่แนบมากับ " นี้ " คำหลัก . และวัตถุเหล่านี้จะได้รับสืบทอดวิธีการและคุณสมบัติที่แนบมากับต้นแบบของฟังก์ชันตัวสร้างบุคคล (ซึ่งเป็นข้อได้เปรียบหลักของวิธีนี้)

โดยวิธีการถ้าคุณต้องการได้รับฟังก์ชั่นเดียวกันกับไวยากรณ์" วัตถุตัวอักษร " คุณจะต้องสร้างชื่อเต็ม () ในทุกวัตถุดังต่อไปนี้:

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();

ในที่สุดถ้าคุณถามว่าทำไมฉันควรใช้วิธีการสร้างฟังก์ชั่นของตัวแทนที่จะเป็นวิธีการตามตัวอักษรวัตถุ :

*** การถ่ายทอดทาง Prototypal ทำให้การสืบทอดสายโซ่เป็นเรื่องง่ายซึ่งมีประโยชน์และมีประสิทธิภาพอย่างมาก

*** มันช่วยประหยัดหน่วยความจำโดยการสืบทอดวิธีการทั่วไปและคุณสมบัติที่กำหนดไว้ในฟังก์ชั่นต้นแบบการสร้าง มิฉะนั้นคุณจะต้องคัดลอกมันซ้ำแล้วซ้ำอีกในวัตถุทั้งหมด

ฉันหวังว่านี่จะสมเหตุสมผล


ขอบคุณ! คาร์ลสำหรับการเพิ่ม "สิ่งนี้" ที่หายไปในวัตถุตามตัวอักษร มันเป็นความผิดพลาดที่น่ากลัว .. ฉันไม่ควรทำผิดแบบนี้
Muba Zubaer Ahammed

"คุณไม่สามารถสืบทอดจากวัตถุที่สร้างด้วยไวยากรณ์ตามตัวอักษร" - ไม่จริง (ฉันเชื่อ) คุณสามารถใช้Object.create(<object defined using literal notation>)หรือnew Object(<object defined using literal notation>)สร้างกลุ่มการสืบทอดได้ตามต้องการ
balajeerc

@ balajeerc ขอบคุณสำหรับความคิดเห็นของคุณ จริงๆแล้วมันควรจะเป็น "คุณไม่สามารถรักษาห่วงโซ่การสืบทอดด้วยวัตถุที่สร้างขึ้นด้วยไวยากรณ์ที่แท้จริง" ผู้ตอบในหลายขั้นตอน: 1. Object.create (): ใช่มันเป็นไปได้ที่จะส่งวัตถุตามตัวอักษรไปและมันจะส่งคืนวัตถุใหม่ซึ่งต้นแบบจะผ่านวัตถุตามตัวอักษร แต่ไม่รู้ว่ามันคือฟังก์ชั่นคอนสตรัคเตอร์หรือจำไม่ได้ว่าตัวอักษรนั้นถูกสร้างขึ้นมา ดังนั้น testobj1.constructor จะส่งคืนฟังก์ชันว่างและจะไม่มีวิธีในการเพิ่มคุณสมบัติ / วิธีการลงในวัตถุนั้นตามตัวอักษรในขณะที่มันเป็นผู้ปกครอง / บรรพบุรุษ
Muba. Zubaer Ahammed

@balajeerc 2. วัตถุใหม่ (): เกือบจะเหมือนกันในกรณีนี้ ยิ่งไปกว่านั้นถ้าคุณคิดถึงเรื่องความจำ แทนที่จะใส่คุณสมบัติและวิธีการลงในต้นแบบมันเพียงแค่คัดลอกทุกอย่างจากวัตถุที่ส่งผ่านตามตัวอักษรและวางลงในวัตถุที่ส่งคืน มันไม่ดีสำหรับหน่วยความจำ ในทางกลับกันฉันมุ่งเน้นไปที่ห่วงโซ่การสืบทอดที่แท้จริงด้วยฟังก์ชั่นคอนสตรัคเตอร์ที่คุณสามารถแก้ไขวิธีการและคุณสมบัติในการบินและวัตถุอื่น ๆ ที่สร้างขึ้นโดยใช้วิธีการคอนสตรัคได้รับผลกระทบเช่นกัน .
Muba. Zubaer Ahammed

@balajeerc ตัวอย่าง: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(); // Zubaer Ahammed john.fullname(); // John Doe zubaer.constructor.prototype.fullname = function() { console.log( 'Hello ' + this.firstname); } zubaer.fullname(); // Hello Zubaer john.fullname(); // Hoello John
Md. Zubaer Ahammed

9

นอกจากนี้ตามหนังสือจาวาสคริปต์บางเล่มของ O'Really .... (อ้างถึง)

อีกเหตุผลสำหรับการใช้ตัวอักษรที่ตรงข้ามกับตัวสร้างวัตถุก็คือว่าไม่มีการแก้ไขขอบเขต เนื่องจากเป็นไปได้ว่าคุณได้สร้าง Constructor ท้องถิ่นที่มีชื่อเดียวกันล่ามจึงต้องค้นหาเชนขอบเขตจากที่ที่คุณเรียก Object () จนสุดจนกว่าจะพบ Construct Object ทั่วโลก


24
รอเป็น O'Really พิมพ์ผิดหรือปุนโดยเจตนา? พวกเขาควรใช้สิ่งนั้นเพื่อทำตลาดหนังสือของพวกเขา!
ทิมโอกิลวี่

3

ฉันพบความแตกต่างหนึ่งอย่างสำหรับ ES6 / ES2015 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 } ]

นี่เป็นเพราะคอมไพเลอร์สับสนโดย{}วงเล็บและคิดว่าn: iเป็นฉลาก:สร้างคำสั่ง ; อัฒภาคเป็นตัวเลือกดังนั้นจึงไม่บ่นเกี่ยวกับมัน

หากคุณเพิ่มคุณสมบัติอื่นไปยังวัตถุในที่สุดก็จะโยนข้อผิดพลาด

$ 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 :

4
คุณยังสามารถใช้ฟังก์ชั่นลูกศร, คุณเพียงแค่ต้องจัดฟันมากขึ้นและผลตอบแทน: [1, 2, 3].map(v => { return {n: v}; });จะสุทธิคุณในสิ่งเดียวกัน ...
นอกรีตลิง

แน่นอนคุณสามารถใช้ฟังก์ชั่นลูกศรปกติสิ่งที่ฉันพูดถึงคือเวอร์ชั่นชวเลขparam => return_valueและความแตกต่างระหว่างการใช้{}และnew Object()ในกรณีนี้
Andrei Simionescu

11
คุณยังคงสามารถใช้ฟังก์ชันชวเลขรุ่นลูกศรและลูกศรปกติได้ เพียงห่อ {n: v} ด้วยวงเล็บหนึ่งคู่:[1, 2, 3].map(v => ({n: v}));
Stephen C

1

อัพเดต 2019

ฉันรันรหัสเดียวกันกับ @rjloura บน OSX High Sierra 10.13.6 โหนดรุ่น 10.13.0 และผลลัพธ์เหล่านี้คือผลลัพธ์

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');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms

-2

การใช้หน่วยความจำจะแตกต่างกันถ้าคุณสร้าง 10,000 อินสแตนซ์ new Object()จะเก็บเพียงหนึ่งสำเนาเท่านั้นในขณะที่{}จะเก็บ 10,000 ชุด


7
newสร้างวัตถุใหม่ พวกเขาทั้งสองใช้หน่วยความจำในปริมาณเท่ากัน
Artyer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.