โหมดการสร้างวัตถุที่ใช้กันทั่วไปหลายโหมด
สร้างด้วยคำหลักใหม่
วิธีพื้นฐานที่สุดในการสร้างวัตถุนั้นไม่มีอะไรมากไปกว่าสิ่งที่ภาษาส่วนใหญ่พูด: หากคุณไม่มีวัตถุคุณจะได้รับใหม่!
var gf = วัตถุใหม่ (); gf.name = "tangwei"; gf.bar = "c ++"; gf.say what = function () {console.log (this.name+"sad: รักคุณตลอดไป");};สร้างด้วยตัวอักษร
สิ่งนี้ดูเหมือนจะเป็นจริง แต่ geeks เช่นวิธีการที่ซับซ้อนและระดับต่ำในการกำหนดตัวแปรได้อย่างไร? ในฐานะที่เป็นภาษาสคริปต์ควรมีสไตล์เดียวกับพี่น้องคนอื่น ๆ ดังนั้นวิธีการกำหนดตัวอักษรวัตถุปรากฏขึ้น:
var gf = {ชื่อ: "tangwei", bar: "c ++", พูดอะไร: function () {console.log (this.name+"เศร้า: รักคุณตลอดไป"); -รูปแบบโรงงาน
ที่จริงแล้วนี่เป็นวิธีการนิยามวัตถุที่ใช้กันมากที่สุดในความเป็นจริง แต่ฉันควรทำอย่างไรถ้าฉันมีวัตถุมากมายที่มีคุณลักษณะที่คล้ายกัน (มันน่าตื่นเต้นที่จะคิดเกี่ยวกับมัน ... )? หากมีการกำหนดหนึ่งคำต่อทีละหนึ่งรหัสจำนวนมากจะถูกสร้างขึ้น ทำไมไม่สร้างโรงงานและมวลผลิตวัตถุของเรา? ดังนั้นทารกที่พองตัวคนแรกในโลกจาวาสคริปต์ - - ไม่ "โมเดลโรงงาน" เกิด!
ฟังก์ชั่น creategf (ชื่อ, bar) {var o = new Object (); o.name = ชื่อ; o.bar = bar; o.say what = function () {Alert (this.name + "Sad: Love You Forever"); } return o;} var gf1 = creategf ("bingbing", "d"); var gf2 = creategf ("mimi", "a");ตัวสร้าง
รูปแบบโรงงานแก้ปัญหาของการสร้างวัตถุที่คล้ายกันหลายอย่าง แต่ปัญหากลับมาอีกครั้ง วัตถุเหล่านี้เกิดขึ้นจากวัตถุ จะแยกแยะประเภทวัตถุเฉพาะได้อย่างไร? ในเวลานี้เราต้องเปลี่ยนไปใช้โหมดอื่นโหมดตัวสร้าง:
ฟังก์ชั่น gf (ชื่อ, บาร์) {this.name = name; this.bar = bar; this.say what = function () {alert (this.name + "กล่าวว่า: รักคุณตลอดไป"); }} var gf1 = ใหม่ gf ("vivian", "f"); var gf2 = ใหม่ gf ("vivian2", "f");ที่นี่เราใช้ตัวสร้างที่เริ่มต้นด้วยตัวพิมพ์ใหญ่เพื่อแทนที่ CreateGF ในตัวอย่างข้างต้น โปรดทราบว่าตัวอักษรตัวแรกของคอนสตรัคเตอร์ควรเป็นตัวพิมพ์ใหญ่ตามอนุสัญญา ที่นี่เราสร้างวัตถุใหม่จากนั้นกำหนดขอบเขตของตัวสร้างให้กับวัตถุใหม่และเรียกใช้วิธีการในตัวสร้าง
ดูเหมือนว่าจะไม่มีอะไรผิดปกติกับวิธีการข้างต้น แต่เราสามารถพบว่าวิธีการพูดในตัวสร้างที่เรียกในสองกรณีไม่ใช่อินสแตนซ์ฟังก์ชั่นเดียวกัน:
console.log (gf1.say what == gf2.say what); //เท็จ
การเรียกใช้วิธีเดียวกัน แต่การประกาศอินสแตนซ์ที่แตกต่างกันคือการสูญเสียทรัพยากร เราสามารถเพิ่มประสิทธิภาพคำแถลงของฟังก์ชั่นคำพูดนอกตัวสร้าง:
ฟังก์ชั่น gf (ชื่อ, บาร์) {this.name = name; this.bar = bar; this.say what = say what} ฟังก์ชั่นบอกว่าอะไร () {แจ้งเตือน (this.name + "เศร้า: รักคุณตลอดไป");}สิ่งนี้ช่วยแก้ปัญหาในการกำหนดอินสแตนซ์วิธีเดียวกันหลายครั้ง แต่ปัญหาใหม่มาอีกครั้ง คำพูดที่เรากำหนดไว้คือวิธีการขอบเขตระดับโลก แต่วิธีนี้ไม่สามารถเรียกได้โดยตรงซึ่งค่อนข้างขัดแย้งกัน จะกำหนดวัตถุที่มีความหรูหรามากขึ้นด้วยการห่อหุ้มบางอย่างได้อย่างไร? ลองดูรูปแบบวัตถุต้นแบบ JavaScript
รูปแบบวัตถุต้นแบบ
เข้าใจวัตถุต้นแบบ
เมื่อเราสร้างฟังก์ชั่นฟังก์ชั่นจะมีแอตทริบิวต์ต้นแบบซึ่งชี้ไปที่วัตถุต้นแบบของฟังก์ชั่นที่สร้างขึ้นผ่านตัวสร้าง ในแง่ของคนธรรมดาวัตถุต้นแบบเป็นวัตถุในหน่วยความจำที่ให้คุณสมบัติและวิธีการที่ใช้ร่วมกันสำหรับวัตถุอื่น ๆ
ในโหมดต้นแบบไม่จำเป็นต้องกำหนดแอตทริบิวต์อินสแตนซ์ในตัวสร้างและข้อมูลแอตทริบิวต์สามารถกำหนดโดยตรงไปยังวัตถุต้นแบบ:
ฟังก์ชั่น gf () {gf.prototype.name = "vivian"; gf.prototype.bar = "C ++"; gf.prototype.say what = function () {Alert (this.name + "Sad: Love You Forever"); }} var gf1 = new gf (); gf1.say what (); var gf2 = new gf ();ความแตกต่างจากตัวสร้างคือคุณสมบัติและวิธีการของวัตถุใหม่สามารถแชร์ได้โดยทุกกรณี กล่าวอีกนัยหนึ่ง GF1 และ GF2 เข้าถึงคุณสมบัติและวิธีการเดียวกัน นอกเหนือจากคุณลักษณะที่เราได้รับมอบหมายแล้วยังมีแอตทริบิวต์ในตัวในวัตถุต้นแบบ วัตถุต้นแบบทั้งหมดมีแอตทริบิวต์ตัวสร้างซึ่งเป็นตัวชี้ไปยังฟังก์ชั่นที่มีแอตทริบิวต์ต้นแบบ (ไม่ว่าคุณจะกล้าไปรอบ ๆ จุดอีกครั้ง!) ผ่านภาพให้แยกกระบวนการบิดนี้ออกมาอย่างชัดเจน:
วัตถุทั้งหมดมีวัตถุต้นแบบ (ต้นแบบ) มีแอตทริบิวต์ตัวสร้างในวัตถุต้นแบบที่ชี้ไปที่ฟังก์ชั่นที่มีแอตทริบิวต์ต้นแบบ อินสแตนซ์ของ GF GF1 และ GF2 ทั้งคู่มีแอตทริบิวต์ภายในที่ชี้ไปที่วัตถุต้นแบบ (โปรโตปรากฏเป็นแอตทริบิวต์ส่วนตัวในเบราว์เซอร์ Firefox) เมื่อเราเข้าถึงแอตทริบิวต์ในวัตถุเราจะถามก่อนว่าวัตถุอินสแตนซ์มีแอตทริบิวต์นี้หรือไม่ ถ้าไม่เราจะค้นหาวัตถุต้นแบบต่อไป
ใช้วัตถุต้นแบบ
ในตัวอย่างก่อนหน้านี้เราสังเกตเห็นว่าเมื่อเพิ่มคุณสมบัติลงในวัตถุต้นแบบเราต้องเพิ่ม gf.prototype ให้กับแต่ละรายการ งานนี้ซ้ำซากมาก ในรูปแบบการสร้างวัตถุข้างต้นเรารู้ว่าสามารถสร้างวัตถุในรูปแบบของตัวอักษร ที่นี่เราสามารถปรับปรุงได้:
ฟังก์ชั่น gf () {} gf.prototype = {ชื่อ: "vivian", bar: "c ++", พูดอะไร: function () {alert (this.name+"Sad: Love You Forever"); -มีสถานที่ที่เราต้องให้ความสนใจเป็นพิเศษ แอตทริบิวต์ตัวสร้างไม่ชี้ไปที่วัตถุ GF อีกต่อไปเนื่องจากทุกครั้งที่มีการกำหนดฟังก์ชั่นวัตถุต้นแบบจะถูกสร้างขึ้นในเวลาเดียวกันและวัตถุนี้จะได้รับแอตทริบิวต์ตัวสร้างใหม่โดยอัตโนมัติ ในสถานที่นี้เราใช้ gf.prototype เพื่อเขียนทับวัตถุต้นแบบต้นฉบับเป็นหลักดังนั้นตัวสร้างได้กลายเป็นแอตทริบิวต์ตัวสร้างของวัตถุใหม่ไม่ชี้ไปที่ GF อีกต่อไป แต่เป็นวัตถุ:
var gf1 = new gf (); console.log (gf1.constructor == gf); // falseconsole.log (gf1.constructor == วัตถุ) // true
โดยทั่วไปการเปลี่ยนแปลงที่ลึกซึ้งนี้จะไม่ส่งผลกระทบต่อเรา แต่ถ้าคุณมีความต้องการพิเศษสำหรับตัวสร้างเราสามารถระบุคุณสมบัติตัวสร้างของ GF.prototype ได้อย่างชัดเจน:
gf.prototype = {constructor: gf, ชื่อ: "vivian", bar: "c ++", พูดอะไร: function () {alert (this.name+"พูดว่า: รักคุณตลอดไป"); }} var gf1 = new gf (); console.log (gf1.constructor == gf); // trueผ่านความเข้าใจเบื้องต้นของรูปแบบวัตถุต้นแบบเราพบว่าวัตถุอินสแตนซ์ทั้งหมดแบ่งปันคุณลักษณะเดียวกันซึ่งเป็นคุณสมบัติพื้นฐานของรูปแบบต้นแบบ แต่บ่อยครั้งนี่คือ "ดาบสองคม" สำหรับนักพัฒนา ในการพัฒนาที่แท้จริงกรณีที่เราหวังว่าควรมีคุณลักษณะของตัวเองซึ่งเป็นเหตุผลหลักว่าทำไมคนไม่กี่คนที่ใช้รูปแบบต้นแบบเพียงอย่างเดียวในการพัฒนาจริง
ตัวสร้างและรูปแบบการรวมต้นแบบ
ในการพัฒนาจริงเราสามารถใช้ตัวสร้างเพื่อกำหนดคุณสมบัติของวัตถุและใช้ต้นแบบเพื่อกำหนดคุณสมบัติและวิธีการที่ใช้ร่วมกันเพื่อให้เราสามารถผ่านพารามิเตอร์ที่แตกต่างกันเพื่อสร้างวัตถุที่แตกต่างกันในขณะที่มีวิธีการและคุณสมบัติที่ใช้ร่วมกัน
ฟังก์ชั่น gf (ชื่อ, บาร์) {this.name = name; this.bar = bar;} gf.prototype = {constructor: gf, พูดอะไร: function () {แจ้งเตือน (this.name + "เศร้า: รักคุณตลอดไป"); }} var gf1 = ใหม่ gf ("vivian", "f"); var gf2 = ใหม่ gf ("vivian1", "c");ในตัวอย่างนี้เรากำหนดค่าคุณสมบัติที่เกี่ยวข้องของวัตถุในฟังก์ชั่นคอนสตรัคเตอร์และกำหนดแอตทริบิวต์คอนสตรัคเตอร์และพูดว่าฟังก์ชั่นใดในวัตถุต้นแบบเพื่อให้ไม่มีผลกระทบระหว่างแอตทริบิวต์ GF1 และ GF2 รูปแบบนี้ยังเป็นวิธีการนิยามวัตถุที่ใช้กันมากที่สุดในการพัฒนาจริงรวมถึงโหมดเริ่มต้นที่นำมาใช้โดยไลบรารี JS จำนวนมาก (bootstrap ฯลฯ )