ความแตกต่างแรกสามารถสรุปได้เป็น: thisหมายถึงอินสแตนซ์ของชั้นเรียน prototypeหมายถึงความหมาย
สมมติว่าเรามีคลาสต่อไปนี้:
var Flight = function ( number ) { this.number = number; };
ดังนั้นที่นี่เราจะแนบthis.numberไปกับทุกตัวอย่างของชั้นเรียนและมันก็สมเหตุสมผลเพราะทุกคนFlightควรมีหมายเลขเที่ยวบินของตัวเอง
var flightOne = new Flight( "ABC" );
var flightTwo = new Flight( "XYZ" );
ในทางตรงกันข้ามprototypeกำหนดคุณสมบัติเดียวที่สามารถเข้าถึงได้โดยทุกกรณี
ตอนนี้ถ้าเราต้องการรับหมายเลขเที่ยวบินเราสามารถเขียนตัวอย่างต่อไปนี้และอินสแตนซ์ทั้งหมดของเราจะได้รับการอ้างอิงไปยังวัตถุต้นแบบใหม่นี้
Flight.prototype.getNumber = function () { return this.number; };
ข้อแตกต่างที่สองเกี่ยวกับวิธีที่ JavaScript ค้นหาคุณสมบัติของวัตถุ เมื่อคุณกำลังค้นหาObject.whateverจาวาสคริปต์จะไปจนถึงวัตถุหลัก(วัตถุที่ทุกอย่างได้สืบทอดมา) และทันทีที่พบการจับคู่มันจะส่งคืนหรือโทรหา
แต่นั่นจะเกิดขึ้นเฉพาะกับคุณสมบัติต้นแบบ ดังนั้นหากคุณมีที่ใดที่หนึ่งในระดับที่สูงกว่าthis.whateverJavaScript จะไม่พิจารณาว่าเป็นการจับคู่และจะทำการค้นหาต่อไป
เรามาดูกันว่ามันเกิดขึ้นจริงอย่างไร
โปรดทราบว่า [เกือบ] ทุกอย่างเป็นวัตถุใน JavaScript ลองสิ่งนี้:
typeof null
ทีนี้เรามาดูกันว่ามีอะไรอยู่ในตัวObject(หมายเหตุตัวพิมพ์ใหญ่Oและตัว.สุดท้าย) ในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Google Chrome เมื่อคุณป้อน.คุณจะได้รับรายการคุณสมบัติที่มีอยู่ภายในวัตถุนั้น
Object.
ตอนนี้ทำสิ่งเดียวกันสำหรับFunction:
Function.
คุณอาจสังเกตเห็นnameวิธีการ เพียงไปและยิงมันขึ้นมาและดูว่าเกิดอะไรขึ้น:
Object.name
Function.name
ตอนนี้มาสร้างฟังก์ชั่น:
var myFunc = function () {};
และลองดูว่าเรามีnameวิธีที่นี่ด้วยหรือไม่:
myFunc.name
คุณควรได้รับสตริงที่ว่างเปล่า แต่ก็ไม่เป็นไร คุณไม่ควรได้รับข้อผิดพลาดหรือข้อยกเว้น
ตอนนี้เราจะเพิ่มบางสิ่งลงในสิ่งที่คล้ายกับพระเจ้าObjectและดูว่าเราได้มันมาในที่อื่นด้วยหรือไม่?
Object.prototype.test = "Okay!";
และไปที่นั่น:
Object.prototype.test
Function.prototype.test
myFunc.prototype.test
"Okay!"ในทุกกรณีที่คุณควรจะเห็น
เกี่ยวกับข้อดีข้อเสียของแต่ละวิธีคุณสามารถพิจารณาการสร้างต้นแบบเป็นวิธีที่ "มีประสิทธิภาพมากขึ้น" ในการทำสิ่งต่าง ๆ เนื่องจากมันจะทำการอ้างอิงในทุก ๆ กรณีแทนที่จะคัดลอกคุณสมบัติทั้งหมดในแต่ละวัตถุ ในอีกทางหนึ่งมันเป็นตัวอย่างของการมีเพศสัมพันธ์อย่างแน่นหนาซึ่งไม่มีข้อห้ามใด ๆ จนกว่าคุณจะพิสูจน์เหตุผลได้อย่างแท้จริง thisค่อนข้างซับซ้อนเนื่องจากเกี่ยวข้องกับบริบท คุณสามารถค้นหาแหล่งข้อมูลที่ดีมากมายได้ฟรีจากอินเทอร์เน็ต
ทั้งหมดนั้นกล่าวว่าทั้งสองวิธีเป็นเพียงเครื่องมือทางภาษาและขึ้นอยู่กับคุณและปัญหาที่คุณพยายามแก้ไขเพื่อเลือกสิ่งที่เหมาะสมยิ่งขึ้น
thisถ้าคุณจะต้องมีคุณสมบัติที่จะมีความเกี่ยวข้องกับตัวอย่างของการเรียนทุกการใช้งานแล้ว prototypeถ้าคุณจะต้องมีคุณสมบัติที่จะทำงานเหมือนกันในทุกกรณีแล้วการใช้งาน
ปรับปรุง
เกี่ยวกับตัวอย่างข้อมูลของคุณตัวอย่างแรกเป็นตัวอย่างของSingletonดังนั้นจึงเหมาะสมที่จะใช้thisภายในวัตถุวัตถุ คุณสามารถปรับปรุงตัวอย่างของคุณโดยทำให้โมดูลเป็นแบบนี้ (และคุณไม่จำเป็นต้องใช้thisเช่นกัน)
/* Assuming it will run in a web browser */
(function (window) {
window.myApp = {
...
}
})( window );
/* And in other pages ... */
(function (myApp) {
myApp.Module = {
...
}
})( myApp );
/* And if you prefer Encapsulation */
(function (myApp) {
myApp.Module = {
"foo": "Foo",
"bar": function ( string ) {
return string;
},
return {
"foor": foo,
"bar": bar
}
}
})( myApp );
ตัวอย่างข้อมูลที่สองของคุณไม่ได้ทำให้ความรู้สึกมากเพราะเป็นครั้งแรกที่คุณใช้thisและต่อมาคุณกำลังพยายามที่จะตัดมันด้วยprototypeซึ่งไม่ได้เพราะต้องใช้ความสำคัญมากกว่าthis prototypeฉันไม่แน่ใจว่าคุณคาดหวังอะไรจากโค้ดส่วนนั้นและวิธีการทำงาน แต่ฉันขอแนะนำให้คุณปรับโครงสร้างใหม่
ปรับปรุง
ในการอธิบายอย่างละเอียดเกี่ยวกับthisการมีความสำคัญเหนือกว่าprototypeฉันสามารถแสดงตัวอย่างและบอกคุณว่ามันสามารถอธิบายได้อย่างไร แต่ฉันไม่มีทรัพยากรภายนอกที่จะสำรอง
ตัวอย่างง่ายมาก:
var myClass = function () { this.foo = "Foo"; };
myClass.prototype.foo = "nice try!";
myClass.prototype.bar = "Bar";
var obj = new myClass;
obj.foo; // Still contains "Foo" ...
obj.bar; // Contains "Bar" as expected
คำอธิบายคือเท่าที่เราทราบthisมีความเกี่ยวข้องกับบริบท ดังนั้นมันจะไม่เกิดขึ้นจนกว่าบริบทจะพร้อม เมื่อบริบทพร้อมหรือยัง เมื่อมีการสร้างอินสแตนซ์ใหม่! คุณควรเดาส่วนที่เหลือตอนนี้! มันหมายความว่าแม้ว่าจะมีprototypeคำจำกัดความ แต่ก็thisมีเหตุผลมากกว่าที่จะต้องมาก่อนเพราะมันเกี่ยวกับอินสแตนซ์ใหม่ที่ถูกสร้างขึ้นในขณะนั้น