สรุปสคีมาในการสร้างวัตถุใน JavaScript
** JavaScript สร้างรูปแบบวัตถุ:
วัตถุ
รูปแบบโรงงาน
โหมดตัวสร้าง
โหมดต้นแบบ
การรวมตัวสร้างและรูปแบบต้นแบบ
โหมดไดนามิกต้นแบบ
-
ภาษาที่มุ่งเน้นวัตถุส่วนใหญ่มีแนวคิดของคลาสซึ่งสามารถสร้างวัตถุหลายอย่างที่มีวิธีการและแอตทริบิวต์เดียวกัน แม้ว่าในทางเทคนิคแล้ว JavaScript เป็นภาษาที่มุ่งเน้นวัตถุ JavaScript ไม่มีแนวคิดของชั้นเรียนทุกอย่างเป็นวัตถุ วัตถุใด ๆ เป็นอินสแตนซ์ของประเภทการอ้างอิงที่แน่นอนและถูกสร้างขึ้นผ่านประเภทการอ้างอิงที่มีอยู่ ประเภทการอ้างอิงสามารถเป็นแบบดั้งเดิมหรือปรับแต่งได้
1. วัตถุตามตัวอักษร
var person = {ชื่อ: 'Nicholas'; อายุ: '22'; Job: "วิศวกรซอฟต์แวร์" SaysName: function () {Alter (this.name); -ในตัวอย่างวัตถุที่มีชื่อบุคคลถูกสร้างขึ้นและแอตทริบิวต์สามรายการ (ชื่ออายุงาน) และวิธีการ (sayname ()) จะถูกเพิ่มเข้าไป วิธีการ sayname () ใช้เพื่อแสดงค่าของ this.name (แก้ไขเป็น person.name)
ตัวอักษรวัตถุสามารถใช้ในการสร้างวัตถุเดียว แต่วิธีนี้มีข้อเสียที่ชัดเจน: การสร้างวัตถุจำนวนมากโดยใช้อินเทอร์เฟซเดียวกันจะสร้างรหัสที่ซ้ำกันจำนวนมาก
2. แบบจำลองโรงงาน
รูปแบบจากโรงงานเป็นรูปแบบการออกแบบที่รู้จักกันดีในสาขาวิศวกรรมซอฟต์แวร์ รูปแบบของโรงงานนามธรรมกระบวนการสร้างวัตถุเฉพาะและใช้ฟังก์ชั่นเพื่อห่อหุ้มรายละเอียดของการสร้างวัตถุด้วยอินเทอร์เฟซเฉพาะ
ฟังก์ชั่น createperson (ชื่อ, อายุ, งาน) {var o = วัตถุใหม่ {}; o.name = ชื่อ; O.AGE = อายุ; o.job = โยบ; o.sayname = function () {Alert (this.name); - return o;} var person1 = creatperson ("Nicholas", 22, "วิศวกรซอฟต์แวร์"); var person2 = creatperson ("greg", 24, "นักเรียน");ฟังก์ชั่น creatperson {} สามารถสร้างวัตถุบุคคลที่มีข้อมูลที่จำเป็นทั้งหมดตามพารามิเตอร์ที่ยอมรับ ฟังก์ชั่นนี้สามารถเรียกได้นับครั้งนับไม่ถ้วนและทุกครั้งที่มันจะส่งคืนวัตถุที่มีคุณสมบัติสามประการและวิธีหนึ่ง
แม้ว่าแบบจำลองโรงงานจะแก้ปัญหาการสร้างวัตถุที่คล้ายกันหลายรายการ แต่ก็ไม่ได้แก้ปัญหาการจดจำวัตถุ (เช่นวิธีการรู้ประเภทของวัตถุ)
3. โหมดตัวสร้าง
ฟังก์ชั่นบุคคล (ชื่อ, อายุ, งาน) {this.name = name; this.age = อายุ; this.job = งาน; this.sayName = function () {Alert (this.name); }} // สร้างอินสแตนซ์ของบุคคลผ่านตัวดำเนินการใหม่ var person1 = บุคคลใหม่ ("นิโคลัส", 22, "วิศวกรซอฟต์แวร์"); var person2 = บุคคลใหม่ ("greg", 24, "นักเรียน"); person1.sayname (); //nicholasperson2.sayname (); // เกร็กความแตกต่างจากแบบจำลองโรงงานคือ
สร้างวัตถุที่ไม่ปรากฏ
กำหนดแอตทริบิวต์และวิธีการโดยตรงกับวัตถุนี้
ไม่มีคำสั่งคืน
ในการสร้างอินสแตนซ์ใหม่ของบุคคลคุณต้องใช้ตัวดำเนินการใหม่ 4 ขั้นตอนในการโทรสร้างตัวสร้าง:
สร้างวัตถุใหม่
กำหนดขอบเขตของตัวสร้างให้กับวัตถุใหม่ (ซึ่งชี้ไปที่วัตถุใหม่นี้)
ดำเนินการรหัสในตัวสร้าง
ส่งคืนวัตถุใหม่
วัตถุทั้งหมดที่สร้างขึ้นในตัวอย่างนี้เป็นทั้งอินสแตนซ์ของอินสแตนซ์ของวัตถุและบุคคล สามารถตรวจสอบได้โดยผู้ให้บริการอินสแตนซ์
การแจ้งเตือน (person1 instanceof object); // true
รูปแบบตัวสร้างยังมีปัญหาของตัวเอง ในความเป็นจริงวิธี Sayname จะถูกสร้างขึ้นใหม่หนึ่งครั้งในแต่ละอินสแตนซ์ ควรสังเกตว่าวิธีการที่สร้างโดยอินสแตนซ์นั้นไม่เท่ากัน รหัสต่อไปนี้สามารถพิสูจน์ได้ว่า
การแจ้งเตือน (person1.sayname == person2.sayname); // false
ปัญหานี้สามารถแก้ไขได้โดยการย้ายวิธีการนอกคอนสตรัคเตอร์เป็นฟังก์ชั่นระดับโลก
ฟังก์ชั่นบุคคล (ชื่อ, อายุ, งาน) {this.name = name; this.age = อายุ; this.job = งาน; } ฟังก์ชั่น saysname () {alert (this.name); -ฟังก์ชั่นระดับโลกที่สร้างขึ้นในโลกโลกสามารถเรียกได้จริงโดยกรณีที่สร้างขึ้นโดยบุคคลซึ่งไม่สมจริงเล็กน้อย หากวัตถุจำเป็นต้องกำหนดวิธีที่ถูกต้องมากฟังก์ชั่นทั่วโลกจำนวนมากจำเป็นต้องกำหนดซึ่งขาดการห่อหุ้ม
4. โหมดต้นแบบ
แต่ละฟังก์ชั่นที่สร้างขึ้นใน JavaScript มีคุณสมบัติต้นแบบซึ่งเป็นตัวชี้ไปยังวัตถุที่มีคุณสมบัติและวิธีการที่สามารถแชร์ได้โดยทุกกรณีของประเภทเฉพาะ (ให้วัตถุทั้งหมดมีคุณสมบัติและวิธีการ)
ฟังก์ชันบุคคล () {} person.prototype.name = "Nicholas"; person.prototype.age = 22; person.prototype.job = "วิศวกรซอฟต์แวร์"; person.prototype.sayname () {Alert (this.name); - var person1 = คนใหม่ (); person1.SayName (); //nicholasalert(person1.sayname == person2.sayname); // trueรหัสข้างต้นทำสิ่งเหล่านี้:
กำหนดบุคคลที่สร้าง ฟังก์ชั่นบุคคลจะได้รับคุณสมบัติต้นแบบโดยอัตโนมัติ คุณสมบัตินี้มีเฉพาะคุณสมบัติตัวสร้างที่ชี้ไปที่บุคคลโดยค่าเริ่มต้น
เพิ่มคุณสมบัติสามอย่างและวิธีการหนึ่งผ่านบุคคล prototype
สร้างอินสแตนซ์ของบุคคลแล้วเรียกใช้เมธอด sayname () บนอินสแตนซ์
การใช้ตัวสร้างบุคคลและบุคคล prototype เพื่อสร้างอินสแตนซ์เป็นตัวอย่างเพื่อแสดงความสัมพันธ์ระหว่างวัตถุ
การใช้ตัวสร้างบุคคลและบุคคล prototype เพื่อสร้างอินสแตนซ์เป็นตัวอย่างเพื่อแสดงความสัมพันธ์ระหว่างวัตถุ
รูปแสดงความสัมพันธ์ระหว่างตัวสร้างบุคคลคุณสมบัติต้นแบบของบุคคลและสองกรณีของบุคคล person.prototype ชี้ไปที่วัตถุต้นแบบ, person.prototype.constructor ชี้กลับไปที่บุคคล นอกเหนือจากการมีแอตทริบิวต์คอนสตรัคเตอร์แล้ววัตถุต้นแบบยังมีคุณสมบัติและวิธีการอื่น ๆ ที่เพิ่มเข้ามาในภายหลัง ทั้งสองอินสแตนซ์ของบุคคลทั้งสองและ person2 มีทรัพย์สินภายในซึ่งชี้ไปที่บุคคลเท่านั้น prototype
กระบวนการโทรของวิธี sayname ():
กำลังมองหาวิธี logname () ในอินสแตนซ์ person1 ฉันพบว่าไม่มีวิธีการดังกล่าวดังนั้นฉันจึงย้อนกลับไปที่ต้นแบบของ Person1
มองหาวิธี Sayame () บนต้นแบบของ person1 มีวิธีนี้ดังนั้นวิธีการที่เรียกว่า
จากกระบวนการค้นหาดังกล่าวเราสามารถป้องกันไม่ให้อินสแตนซ์เข้าถึงแอตทริบิวต์ชื่อเดียวกันบนต้นแบบโดยกำหนดแอตทริบิวต์ชื่อเดียวกันในต้นแบบในอินสแตนซ์ ควรสังเกตว่าการทำเช่นนั้นจะไม่ลบแอตทริบิวต์ชื่อเดียวกันบนต้นแบบ แต่จะป้องกันไม่ให้อินสแตนซ์เข้าถึงเท่านั้น
ฟังก์ชันบุคคล () {} person.prototype.name = "Nicholas"; person.prototype.age = 22; person.prototype.job = "วิศวกรซอฟต์แวร์"; person.prototype.sayname () {Alert (this.name); - var person1 = คนใหม่ (); var person2 = คนใหม่ (); person1.name = "greg" การแจ้งเตือน (person1.name) // greg มาจากการแจ้งเตือนอินสแตนซ์ (person2.name) // nicholas มาจากต้นแบบใช้ตัวดำเนินการลบเพื่อลบคุณสมบัติอินสแตนซ์อย่างสมบูรณ์
ลบ person1.name; Alert (person1.name) // Nicholas จากต้นแบบ
ใช้วิธีการ hasownproperty () เพื่อตรวจสอบว่ามีคุณสมบัติอยู่ในอินสแตนซ์หรือต้นแบบ
ฟังก์ชันบุคคล () {} person.prototype.name = "Nicholas"; person.prototype.age = 22; person.prototype.job = "วิศวกรซอฟต์แวร์"; person.prototype.sayname () {Alert (this.name); - var person1 = คนใหม่ (); var person2 = คนใหม่ (); การแจ้งเตือน (person1, hasownproperty ("ชื่อ")); // false person1.name = "greg" การแจ้งเตือน (person1.name) // greg จากการแจ้งเตือนอินสแตนซ์ (person1, hasownproperty ("name")); // truealert (person2.name) person1.name; Alert (person1.name) // Nicholas จากการแจ้งเตือนต้นแบบ (person1, hasownproperty ("ชื่อ")); // falseรูปต่อไปนี้แสดงความสัมพันธ์ระหว่างอินสแตนซ์และต้นแบบในสถานการณ์ที่แตกต่างกัน
ไวยากรณ์ต้นแบบอย่างง่าย
Function Person () {} person.prototype = {ชื่อ: "Nicholas", อายุ: 22, Job: "Software Engineer", sayname: function () {Alert (this.name); -ในรหัสข้างต้นแอตทริบิวต์ตัวสร้างไม่ชี้ไปที่บุคคลอีกต่อไปและประเภทของวัตถุไม่สามารถกำหนดได้ผ่านตัวสร้าง คุณสามารถตั้งค่ากลับเป็นค่าที่เหมาะสมเช่นด้านล่าง
Function Person () {} person.prototype = {constructor: บุคคล, ชื่อ: "Nicholas", อายุ: 22, งาน: "วิศวกรซอฟต์แวร์", sayname: function () {Alert (this.name); -การรีเซ็ตคุณสมบัติตัวสร้างจะทำให้คุณสมบัติ [[enumerable]] ของมันถูกตั้งค่าเป็นจริง โดยค่าเริ่มต้นคุณสมบัติตัวสร้างเนทีฟไม่สามารถระบุได้ คุณสามารถใช้เมธอด object.defineProperty () เพื่อเปลี่ยน
Object.defineProperty (person.prototype, "Constructor", {Enumerable: False, Value: Person});กระบวนการค้นหาค่าในต้นแบบคือการค้นหาและการแก้ไขใด ๆ ที่ทำโดยวัตถุต้นแบบสามารถสะท้อนได้ทันทีจากอินสแตนซ์
var friend = คนใหม่ (); person.prototype.sayhi = function () {แจ้งเตือน ("hi);} เพื่อน, sayhi (); //" สวัสดี "(ไม่มีปัญหา)อินสแตนซ์ของบุคคลนั้นถูกสร้างขึ้นก่อนที่จะเพิ่มวิธีการใหม่ แต่ยังสามารถเข้าถึงวิธีที่เพิ่มขึ้นใหม่ได้เนื่องจากการเชื่อมต่อแบบหลวมระหว่างอินสแตนซ์และต้นแบบ
สถานการณ์หลังจากเขียนวัตถุต้นแบบใหม่
ฟังก์ชันบุคคล () {} var friend = คนใหม่ (); person.prototype = {ชื่อ: "Nicholas", อายุ: 22, งาน: "วิศวกรซอฟต์แวร์", sayname: function () {alert (this.name); - friend.sayname (); // ข้อผิดพลาดเหตุผลสำหรับข้อผิดพลาดเมื่อโทรหาเพื่อน sayname () คือต้นแบบที่ชี้ไปที่เพื่อนไม่มีคุณสมบัติที่ตั้งชื่อตามฟิลด์นี้ดังแสดงในรูปด้านล่าง
ปัญหาวัตถุต้นแบบ
วัตถุต้นแบบตัดกระบวนการของการผ่านการเริ่มต้นพารามิเตอร์สำหรับตัวสร้างและแรงทั้งหมดได้รับค่าแอตทริบิวต์เดียวกันโดยค่าเริ่มต้น ปัญหาที่ใหญ่ที่สุดของแบบจำลองต้นแบบคือพวกเขามีลักษณะร่วมกันของพวกเขา เมื่อโมเดลต้นแบบมีคุณสมบัติของประเภทอ้างอิงปัญหาจะรุนแรงขึ้น ลองดูตัวอย่างต่อไปนี้
ฟังก์ชันบุคคล () {} person.prototype = {constructor: บุคคล, ชื่อ: "Nicholas", อายุ: 22, งาน: "วิศวกรซอฟต์แวร์", เพื่อน: ["Shelby", "ศาล"], sayname: function () {แจ้งเตือน (นี่คือชื่อ); - var person1 = คนใหม่ (); var person2 = คนใหม่ (); person1.friend.push ("van"); การแจ้งเตือน (person1.friends); // "Shelby, Court, Van" Alert (person2.friends); // "Shelby, Court, Van" Alert (person1.friends == person2.friends); // true5. การรวมโหมดตัวสร้างและโหมดต้นแบบ
ในการรวมกันของโหมดคอนสตรัคเตอร์และโหมดต้นแบบตัวสร้างจะใช้เพื่อกำหนดคุณสมบัติอินสแตนซ์และแบบจำลองต้นแบบจะใช้เพื่อกำหนดวิธีการและคุณสมบัติที่ใช้ร่วมกัน ด้วยวิธีนี้แต่ละอินสแตนซ์จะมีสำเนาของแอตทริบิวต์อินสแตนซ์ของตัวเองและยังสามารถแชร์การอ้างอิงไปยังวิธีการบันทึกหน่วยความจำให้มากที่สุด
ฟังก์ชั่นบุคคล (ชื่อ, อายุ, งาน) {this.name = name; this.age = อายุ; this.job = งาน; this.friends = ["Shelby", "Court"];} person.prototype = {constructor: person, sayname: function () {alert (this.name); }} var person1 = บุคคลใหม่ ("นิโคลัส", 22, "วิศวกรซอฟต์แวร์"); var person2 = บุคคลใหม่ ("greg", 24, "นักเรียน"); person1.friend.push ("van"); การแจ้งเตือน (person1.friends); // "Shelby, Court, Van" Alert (person2.friends); // "Shelby, ศาล" แจ้งเตือน (person1.friends == person2.friends); // การแจ้งเตือนเท็จ (person1.sayname == person2.sayname);6. โหมดต้นแบบไดนามิก
โหมดไดนามิกต้นแบบห่อหุ้มข้อมูลทั้งหมดที่จำเป็นในตัวสร้างและใช้คำสั่ง IF เพื่อพิจารณาว่ามีคุณสมบัติบางอย่างในต้นแบบหรือไม่ หากไม่มีอยู่ (เมื่อตัวสร้างถูกเรียกเป็นครั้งแรก) ให้ดำเนินการรหัสการเริ่มต้นต้นแบบภายในคำสั่ง IF
ฟังก์ชั่นบุคคล (ชื่ออายุ) {this.name = name; this.age = อายุ; this.job = Job; // เมธอดถ้า (typeof this.sayname! = 'function') {person.prototype.sayname = function () {Alert (this.name); - }} var friend = บุคคลใหม่ ('nicholas', '22', 'วิศวกรซอฟต์แวร์'); // ตัวสร้างถูกเรียกเป็นครั้งแรกและต้นแบบได้รับการแก้ไขในเวลานี้ var person2 = คนใหม่ ('Amy', '21');แนะนำการอ่าน:
หลายวิธีทั่วไปในการสร้างวัตถุใน JS Object-oriented (โหมดโรงงานโหมดตัวสร้างโหมดต้นแบบ)
ด้านบนเป็นรูปแบบของการสร้างวัตถุใน JavaScript ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน!