แนะนำ
การเขียนโปรแกรมใด ๆ เสนอการใช้รหัสซ้ำ มิฉะนั้นหากคุณต้องการเขียนโปรแกรมใหม่ทุกครั้งที่คุณพัฒนาโปรแกรมใหม่หรือเขียนฟังก์ชั่นใหม่ก็จะเป็นการเสีย อย่างไรก็ตามการใช้รหัสซ้ำก็ดีหรือไม่ดี ในสองบทความถัดไปเราจะหารือเกี่ยวกับการใช้รหัสซ้ำ บทความแรกหลีกเลี่ยงการใช้รูปแบบเหล่านี้ให้มากที่สุดเพราะมันนำปัญหาบางอย่างในระดับที่มากขึ้นหรือน้อยลง แถวที่สองคือคำแนะนำซึ่งหมายถึงรูปแบบที่แนะนำที่ทุกคนใช้และโดยทั่วไปจะไม่มีปัญหา
โหมด 1: โหมดเริ่มต้น
มักจะมีปัญหาเกี่ยวกับการใช้รหัสซ้ำของโหมดเริ่มต้นที่ทุกคนใช้โดยทั่วไป โหมดนี้ใช้ตัวสร้างของ Parent () เพื่อสร้างวัตถุและกำหนดวัตถุให้กับต้นแบบเด็ก () มาดูรหัส:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นสืบทอด (c, p) {
C.prototype = ใหม่ p ();
-
// ตัวสร้างหลัก
ฟังก์ชันพาเรนต์ (ชื่อ) {
this.name = name || 'อดัม';
-
// เพิ่มฟังก์ชั่นพูดลงในต้นแบบ
parent.prototype.say = function () {
ส่งคืนสิ่งนี้ชื่อ;
-
// ตัวสร้างเด็กว่างเปล่า
ฟังก์ชั่นเด็ก (ชื่อ) {
-
// ดำเนินการมรดก
สืบทอด (เด็กผู้ปกครอง);
var kid = เด็กใหม่ ();
console.log (kid.say ()); // "อดัม"
var kiddo = เด็กใหม่ ();
kiddo.name = "Patrick";
console.log (kiddo.say ()); // "แพทริค"
// ข้อเสีย: คุณไม่สามารถส่งพารามิเตอร์ไปยังตัวสร้างเด็ก
var s = เด็กใหม่ ('seth');
console.log (s.say ()); // "อดัม"
ข้อเสียของโหมดนี้คือเด็กไม่สามารถผ่านพารามิเตอร์ซึ่งโดยทั่วไปแล้วไร้ประโยชน์
รูปแบบที่ 2: ยืมตัวสร้าง
รูปแบบนี้คือเด็กยืมตัวสร้างของผู้ปกครองที่จะใช้แล้วส่งผ่านสิ่งนี้และพารามิเตอร์ไปยังวิธีการสมัคร:
การคัดลอกรหัสมีดังนี้:
// ตัวสร้างหลัก
ฟังก์ชันพาเรนต์ (ชื่อ) {
this.name = name || 'อดัม';
-
// เพิ่มฟังก์ชั่นพูดลงในต้นแบบ
parent.prototype.say = function () {
ส่งคืนสิ่งนี้ชื่อ;
-
// ตัวสร้างเด็ก
ฟังก์ชั่นเด็ก (ชื่อ) {
parent.apply (นี่, อาร์กิวเมนต์);
-
var kid = เด็กใหม่ ("Patrick");
console.log (kid.name); // "แพทริค"
// ข้อเสีย: วิธีการพูดไม่ได้รับมาจากตัวสร้าง
console.log (typeof kid.say); // "ไม่ได้กำหนด"
ข้อเสียยังชัดเจนและวิธีการพูดไม่สามารถใช้ได้เพราะมันยังไม่ได้รับการสืบทอด
รูปแบบที่ 3: ยืมตัวสร้างและตั้งต้นแบบ
สองโหมดข้างต้นมีข้อบกพร่องของตัวเองดังนั้นจะลบข้อบกพร่องของทั้งคู่ได้อย่างไร? ลองกันเถอะ:
การคัดลอกรหัสมีดังนี้:
// ตัวสร้างหลัก
ฟังก์ชันพาเรนต์ (ชื่อ) {
this.name = name || 'อดัม';
-
// เพิ่มฟังก์ชั่นพูดลงในต้นแบบ
parent.prototype.say = function () {
ส่งคืนสิ่งนี้ชื่อ;
-
// ตัวสร้างเด็ก
ฟังก์ชั่นเด็ก (ชื่อ) {
parent.apply (นี่, อาร์กิวเมนต์);
-
child.prototype = ผู้ปกครองใหม่ ();
var kid = เด็กใหม่ ("Patrick");
console.log (kid.name); // "แพทริค"
console.log (typeof kid.say); // การทำงาน
console.log (kid.say ()); // แพทริค
console.dir (เด็ก);
ลบ kid.name;
console.log (kid.say ()); // "อดัม"
เมื่อมันทำงานทุกอย่างเป็นเรื่องปกติ แต่คุณสังเกตเห็นว่าตัวสร้างหลักถูกดำเนินการสองครั้งดังนั้นแม้ว่าโปรแกรมจะพร้อมใช้งาน แต่ก็ไม่มีประสิทธิภาพมาก
โหมด 4: ต้นแบบที่ใช้ร่วมกัน
ต้นแบบที่ใช้ร่วมกันหมายความว่าเด็กและผู้ปกครองใช้ต้นแบบเดียวกันรหัสมีดังนี้:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นสืบทอด (c, p) {
C.prototype = P.Prototype;
-
// ตัวสร้างหลัก
ฟังก์ชันพาเรนต์ (ชื่อ) {
this.name = name || 'อดัม';
-
// เพิ่มฟังก์ชั่นพูดลงในต้นแบบ
parent.prototype.say = function () {
ส่งคืนสิ่งนี้ชื่อ;
-
// ตัวสร้างเด็ก
ฟังก์ชั่นเด็ก (ชื่อ) {
-
สืบทอด (เด็กผู้ปกครอง);
var kid = เด็กใหม่ ('Patrick');
console.log (kid.name); // ไม่ได้กำหนด
console.log (typeof kid.say); // การทำงาน
kid.name = 'Patrick';
console.log (kid.say ()); // แพทริค
console.dir (เด็ก);
แน่นอนว่าสิ่งเดียวกันนี้เป็นจริงพารามิเตอร์ของเด็กไม่ได้รับอย่างถูกต้อง
รูปแบบที่ 5: ตัวสร้างชั่วคราว
ก่อนอื่นให้ยืมตัวสร้างจากนั้นตั้งต้นแบบเด็กเป็นอินสแตนซ์ของตัวสร้างที่ยืมมาและในที่สุดก็คืนค่าตัวสร้างของต้นแบบเด็ก รหัสมีดังนี้:
การคัดลอกรหัสมีดังนี้:
/* ปิด*/
var angerit = (function () {
var f = function () {
-
ฟังก์ชั่น return (c, p) {
f.prototype = p.prototype;
C.prototype = new f ();
c.uber = p.prototype;
C.prototype.Constructor = C;
-
-
ฟังก์ชันพาเรนต์ (ชื่อ) {
this.name = name || 'อดัม';
-
// เพิ่มฟังก์ชั่นพูดลงในต้นแบบ
parent.prototype.say = function () {
ส่งคืนสิ่งนี้ชื่อ;
-
// ตัวสร้างเด็ก
ฟังก์ชั่นเด็ก (ชื่อ) {
-
สืบทอด (เด็กผู้ปกครอง);
var kid = เด็กใหม่ ();
console.log (kid.name); // ไม่ได้กำหนด
console.log (typeof kid.say); // การทำงาน
kid.name = 'Patrick';
console.log (kid.say ()); // แพทริค
var kid2 = เด็กใหม่ ("ทอม");
console.log (kid.say ());
console.log (kid.constructor.name); // เด็ก
console.log (kid.constructor === ผู้ปกครอง); // เท็จ
ปัญหายังคงเหมือนเดิมเด็กไม่สามารถรับพารามิเตอร์ได้ตามปกติ
โหมด 6: Klass
เริ่มต้นด้วยรหัสสำหรับรูปแบบนี้:
การคัดลอกรหัสมีดังนี้:
var klass = function (parent, อุปกรณ์ประกอบฉาก) {
var child, f, i;
// 1.
// ตัวสร้างใหม่
child = function () {
if (child.uber && child.uber.hasownproperty ("__ construct")) {
child.uber .__ construct.apply (นี่, ข้อโต้แย้ง);
-
if (child.prototype.hasownproperty ("__ construct")) {
child.prototype .__ construct.apply (นี่, อาร์กิวเมนต์);
-
-
// 2.
// มรดก
ผู้ปกครอง = ผู้ปกครอง || วัตถุ;
f = function () {
-
f.prototype = parent.prototype;
child.prototype = new f ();
child.uber = parent.prototype;
child.prototype.constructor = เด็ก;
// 3.
// เพิ่มวิธีการใช้งาน
สำหรับ (ฉันอยู่ในอุปกรณ์ประกอบฉาก) {
if (props.hasownproperty (i)) {
child.prototype [i] = อุปกรณ์ประกอบฉาก [i];
-
-
// ส่งคืน "คลาส"
เด็กกลับ;
-
var man = klass (null, {
__Construct: ฟังก์ชั่น (อะไร) {
console.log ("ตัวสร้างมนุษย์");
this.name = อะไร;
-
getName: function () {
ส่งคืนสิ่งนี้ชื่อ;
-
-
var first = คนใหม่ ('Adam'); // บันทึก "ตัวสร้างมนุษย์"
First.getName (); // "อดัม"
var superman = klass (man, {
__Construct: ฟังก์ชั่น (อะไร) {
console.log ("ตัวสร้างของซูเปอร์แมน");
-
getName: function () {
var name = superman.uber.getName.call (นี่);
กลับ "ฉันเป็น" + ชื่อ;
-
-
var Clark = New Superman ('Clark Kent');
Clark.getName (); // "ฉันคือคลาร์กเคนต์"
console.log (คลาร์กอินสแตนซ์ของมนุษย์); // จริง
console.log (คลาร์กอินสแตนซ์ของซูเปอร์แมน); // จริง
แล้วล่ะ? มันวิงเวียนเล็กน้อยหรือไม่? เพื่อให้ดีไวยากรณ์และข้อกำหนดของรูปแบบนี้เหมือนกับภาษาอื่น ๆ คุณเต็มใจที่จะใช้หรือไม่? ไอ. - -
สรุป
แม้ว่าหกโหมดข้างต้นใช้ฟังก์ชั่นบางอย่างในสถานการณ์พิเศษบางอย่างพวกเขาทั้งหมดมีข้อบกพร่องของตัวเองดังนั้นโดยทั่วไปทุกคนควรหลีกเลี่ยงการใช้งาน