Polymorphism ใน Javascript คืออะไร?


92

ผมได้อ่านบทความที่เป็นไปได้บางอย่างที่ฉันสามารถพบได้บนอินเทอร์เน็ตในหลายรูปแบบ แต่ฉันคิดว่าฉันไม่สามารถเข้าใจความหมายและความสำคัญของมันได้ บทความส่วนใหญ่ไม่ได้บอกว่าเหตุใดจึงสำคัญและฉันจะบรรลุพฤติกรรมหลายรูปแบบใน OOP ได้อย่างไร (แน่นอนใน JavaScript)

ฉันไม่สามารถให้ตัวอย่างโค้ดใด ๆ ได้เนื่องจากฉันไม่มีแนวคิดในการใช้งานดังนั้นคำถามของฉันอยู่ด้านล่าง

  1. มันคืออะไร?
  2. ทำไมเราถึงต้องการ?
  3. มันทำงานอย่างไร?
  4. ฉันจะบรรลุพฤติกรรมหลายรูปแบบนี้ในจาวาสคริปต์ได้อย่างไร

ฉันมีตัวอย่างนี้ แต่เข้าใจได้ง่ายว่าผลของรหัสนี้จะเป็นอย่างไร ไม่ได้ให้ความคิดที่ชัดเจนเกี่ยวกับความหลากหลายของตัวเอง

function Person(age, weight) {
    this.age = age;
    this.weight = weight;
    this.getInfo = function() {
        return "I am " + this.age + " years old " +
        "and weighs " + this.weight +" kilo.";
    }
}
function Employee(age, weight, salary) {
    this.salary = salary;
    this.age = age;
    this.weight = weight;
    this.getInfo = function() {
        return "I am " + this.age + " years old " +
        "and weighs " + this.weight +" kilo " +
        "and earns " + this.salary + " dollar.";
    }
}

Employee.prototype = new Person();
Employee.prototype.constructor = Employee;
  // The argument, 'obj', can be of any kind
  // which method, getInfo(), to be executed depend on the object
  // that 'obj' refer to.

function showInfo(obj) {
    document.write(obj.getInfo() + "<br>");
}

var person = new Person(50,90);
var employee = new Employee(43,80,50000);
showInfo(person);
showInfo(employee);

คำถามนี้อาจกว้างเกินไปที่จะทำงานได้ดีกับ StackOverflow สิ่งที่ดีที่สุดที่เราทำได้คือการเชื่อมโยงคุณกับคำอธิบายเกี่ยวกับความหลากหลายอื่น ๆ StackOverflow ดีที่สุดในการตอบคำถามหรือคำชี้แจงเกี่ยวกับปัญหาที่เฉพาะเจาะจงเช่น "แหล่งที่มากล่าวว่าพหุนามคือ XYZ แต่ Y หมายถึงอะไร"
Vitruvius

2
คุณไม่ต้องการมัน เลย. คุณไม่จำเป็นต้องเรียนใน JS ด้วยซ้ำและในความเป็นจริงยังมีกระบวนทัศน์อื่น ๆ อีกมากมายที่ดีกว่าสำหรับการสร้างแอป ใช้ / โทร / ผูกไม่จำเป็นต้องมีความเป็นเนื้อเดียวกันและด้วย soft-object คุณสามารถปรับเปลี่ยนอะไรก็ได้เพื่อให้เหมาะกับความต้องการของคุณโดยไม่ต้องตกแต่งล่วงหน้าหรือสืบทอดกรณีพิเศษ
dandavis

1
Polymorphism ไม่ได้เกี่ยวข้องกับ OO เท่านั้น แต่ยังมีความหมายอีกมากมาย คุณอาจต้องการที่จะอ่านคำตอบอื่น ๆ ภายใต้คำถามคือความแตกต่างที่เป็นไปได้โดยไม่ต้องมรดก
Edwin Dalorzo

การสืบทอดมักทำอย่างไม่ถูกต้องใน JavaScript ในการสร้างอินสแตนซ์ของ Parent เพื่อใช้เป็นต้นแบบของ Child แสดงให้เห็นถึงการขาดความเข้าใจในบทบาทของฟังก์ชันตัวสร้างและการเล่นต้นแบบในการกำหนดและสร้างอ็อบเจ็กต์ มีข้อมูลเพิ่มเติมในคำตอบนี้: stackoverflow.com/a/16063711/1641941
HMR

คำตอบ:


99

Polymorphism เป็นหนึ่งในหลักการของ Object Oriented Programming (OOP) เป็นการฝึกฝนการออกแบบออบเจ็กต์เพื่อแชร์พฤติกรรมและสามารถลบล้างพฤติกรรมที่ใช้ร่วมกันกับสิ่งที่เฉพาะเจาะจงได้ Polymorphism ใช้ประโยชน์จากการถ่ายทอดทางพันธุกรรมเพื่อให้สิ่งนี้เกิดขึ้น

ใน OOP ถือว่าทุกสิ่งถูกจำลองเป็นวัตถุ สิ่งที่เป็นนามธรรมนี้สามารถนำไปรวมกับน๊อตและสลักเกลียวสำหรับรถยนต์หรือกว้างพอ ๆ กับประเภทรถที่มีปียี่ห้อและรุ่น

ในการมีสถานการณ์รถหลายรูปแบบจะมีประเภทรถพื้นฐานจากนั้นจะมีคลาสย่อยที่จะสืบทอดมาจากรถยนต์และให้พฤติกรรมของตัวเองอยู่เหนือพฤติกรรมพื้นฐานที่รถยนต์จะมี ตัวอย่างเช่นคลาสย่อยอาจเป็น TowTruck ซึ่งจะยังคงมียี่ห้อและรุ่นปี แต่อาจมีพฤติกรรมและคุณสมบัติพิเศษบางอย่างซึ่งอาจเป็นพื้นฐานพอ ๆ กับค่าสถานะสำหรับ IsTowing ที่ซับซ้อนพอ ๆ กับลักษณะเฉพาะของลิฟต์

ย้อนกลับไปที่ตัวอย่างของคนและพนักงานพนักงานทุกคนเป็นคน แต่ทุกคนไม่ใช่พนักงาน ซึ่งกล่าวได้ว่าผู้คนจะเป็นชนชั้นสูงและเป็นพนักงานระดับย่อย คนเราอาจมีอายุและน้ำหนัก แต่ไม่มีเงินเดือน พนักงานเป็นคนดังนั้นพวกเขาจะมีอายุและน้ำหนักโดยกำเนิด แต่เนื่องจากพวกเขาเป็นพนักงานพวกเขาจะมีเงินเดือน

ดังนั้นเพื่ออำนวยความสะดวกในเรื่องนี้ก่อนอื่นเราจะเขียน super class (Person)

function Person(age,weight){
 this.age = age;
 this.weight = weight;
}

และเราจะให้บุคคลสามารถแบ่งปันข้อมูลของพวกเขา

Person.prototype.getInfo = function(){
 return "I am " + this.age + " years old " +
    "and weighs " + this.weight +" kilo.";
};

ต่อไปเราต้องการที่จะมีคลาสย่อยของบุคคลพนักงาน

function Employee(age,weight,salary){
 this.age = age;
 this.weight = weight;
 this.salary = salary;
}
Employee.prototype = new Person();

และเราจะลบล้างพฤติกรรมของ getInfo โดยการกำหนดพฤติกรรมที่เหมาะสมกับพนักงานมากกว่า

Employee.prototype.getInfo = function(){
 return "I am " + this.age + " years old " +
    "and weighs " + this.weight +" kilo " +
    "and earns " + this.salary + " dollar.";  
};

สิ่งเหล่านี้สามารถใช้ได้เหมือนกับการใช้รหัสเดิมของคุณ

var person = new Person(50,90);
var employee = new Employee(43,80,50000);

console.log(person.getInfo());
console.log(employee.getInfo());

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


2
@ user3138436 - ถูกต้อง ห่วงโซ่ต้นแบบจะได้รับการตรวจสอบว่าเกิดขึ้นครั้งแรกgetInfoซึ่งจะเป็นของพนักงานเนื่องจากอยู่ในห่วงโซ่สูงกว่าของบุคคล นั่นคือสิ่งที่ฉันหมายถึงเมื่อฉันพูดว่า "ลบล้าง"
Travis J

17
คุณไม่ได้ใช้คอนสตรัคเตอร์ (Person.call (this, arg)) และตั้งค่า Employee prototype เป็นอินสแตนซ์ของ Person Prototype คือที่ที่สมาชิกที่ใช้ร่วมกันไปและฟังก์ชันตัวสร้างคือที่ที่สร้างสมาชิกเฉพาะอินสแตนซ์ ตัวอย่างของคุณใช้การคัดลอกวางโค้ดโดยใช้ฟังก์ชันตัวสร้างซ้ำและสืบทอดส่วนต้นแบบผิด (บุคคลมีสมาชิกเฉพาะตัวอย่างที่ไม่มีธุรกิจอยู่ใน Employee.prototype โดยเฉพาะอย่างยิ่งหากคุณมีสมาชิกที่ไม่แน่นอน ข้อมูลเพิ่มเติมเกี่ยวกับการสืบทอดโดยใช้ฟังก์ชันตัวสร้างและต้นแบบที่นี่: stackoverflow.com/a/16063711/1641941
HMR

3
สำหรับพนักงานที่จะใช้ซ้ำและขยายการรับข้อมูลของบุคคลนั้นสามารถทำได้return Person.prototype.getInfo.call(this) + + "and earns " + this.salary + " dollar.";แทนที่จะคัดลอกวางโค้ดกลับมาใช้ใหม่
HMR

3
ที่นี่มีการประยุกต์ใช้ความหลากหลาย
albert Jegani

2
@rpeg จุดของความหลากหลายสามารถมองเห็นได้ดีขึ้นในตัวอย่าง OPs ฟังก์ชัน showInfo (); ยอมรับวัตถุทั่วไป ความหลากหลายในตอนนี้คือความสามารถในการตอบสนองที่แตกต่างกันขึ้นอยู่กับประเภทของวัตถุ ฉันคิดว่าคำตอบนี้ไม่ชัดเจนเพียงพอเนื่องจากมันเรียก getInfo () ในทุกออบเจ็กต์เฉพาะ
Stefan

26

ตามที่อธิบายไว้ในคำตอบอื่น ๆความหลากหลายมีการตีความที่แตกต่างกัน

คำอธิบายที่ดีที่สุดในเรื่องที่ฉันเคยอ่านคือบทความของLuca Cardelliนักทฤษฎีประเภทที่มีชื่อเสียง บทความนี้เป็นชื่อในการทำความเข้าใจชนิดข้อมูลนามธรรมและความแตกต่าง

มันคืออะไร?

Cardelli กำหนดความหลากหลายของความหลากหลายในบทความนี้:

  • สากล
    • พาราเมตริก
    • การรวม
  • สำหรับสิ่งนี้สิ่งนั้นโดยเฉพาะ
    • การบรรทุกมากเกินไป
    • การบีบบังคับ

บางทีใน JavaScript มันยากกว่าเล็กน้อยที่จะเห็นผลของความหลากหลายเนื่องจากความหลากหลายแบบคลาสสิกกว่านั้นมีความชัดเจนมากกว่าในระบบประเภทคงที่ในขณะที่ JavaScript มีระบบประเภทไดนามิก

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

อย่างไรก็ตาม JavaScript มีรูปแบบของการสืบทอดประเภทที่เลียนแบบแนวคิดเดียวกันของความหลากหลายประเภทย่อย (จำแนกเป็น polymorphism รวมโดย Cardelli ด้านบน) ในลักษณะเดียวกับที่เราทำในภาษาโปรแกรมเชิงวัตถุอื่น ๆ เช่น Java หรือ C # (ตามที่อธิบายไว้ใน คำตอบอื่นที่ฉันแบ่งปันด้านบน)

รูปแบบของความแตกต่างอย่างมากโดยทั่วไปในภาษาแบบไดนามิกอื่นเรียกว่าเป็ดพิมพ์

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

ทำไมเราถึงต้องการ?

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

มันทำงานอย่างไร?

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

หัวเรื่องค่อนข้างกว้างและคุณเปิดคำถามสองข้อในโพสต์เดียว บางทีอาจเป็นการดีที่สุดที่คุณจะเริ่มต้นด้วยการอ่านบทความของ Cardelli แล้วพยายามทำความเข้าใจเกี่ยวกับความหลากหลายโดยไม่คำนึงถึงภาษาหรือกระบวนทัศน์การเขียนโปรแกรมใด ๆ จากนั้นคุณจะเริ่มสร้างความเชื่อมโยงระหว่างแนวคิดทางทฤษฎีกับสิ่งที่ภาษาเฉพาะเช่น JavaScript เสนอเพื่อนำแนวคิดเหล่านั้นไปใช้


14

จุดประสงค์ของความหลากหลายคืออะไร?

ความหลากหลายทำให้ระบบประเภทคงที่มีความยืดหยุ่นมากขึ้นโดยไม่สูญเสียความปลอดภัยประเภทคงที่ (อย่างมีนัยสำคัญ) โดยการคลายเงื่อนไขสำหรับการเทียบเท่าประเภท หลักฐานยังคงอยู่ว่าโปรแกรมจะทำงานก็ต่อเมื่อไม่มีข้อผิดพลาดประเภทใด ๆ

ฟังก์ชัน polymorphic หรือชนิดข้อมูลมีความกว้างมากกว่า monomorphic เนื่องจากสามารถใช้ในสถานการณ์ที่กว้างขึ้นได้ ในแง่นี้ความหลากหลายแสดงถึงแนวคิดของการวางนัยทั่วไปในภาษาที่พิมพ์อย่างเคร่งครัด

สิ่งนี้ใช้กับ Javascript ได้อย่างไร?

Javascript มีระบบประเภทไดนามิกที่อ่อนแอ ระบบประเภทดังกล่าวเทียบเท่ากับระบบประเภทที่เข้มงวดซึ่งมีเพียงประเภทเดียว เราสามารถคิดว่าประเภทนี้เป็นประเภทยูเนี่ยนขนาดใหญ่ (ไวยากรณ์หลอก):

type T =
 | Undefined
 | Null
 | Number
 | String
 | Boolean
 | Symbol
 | Object
 | Array
 | Map
 | ...

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

หากเราใช้มุมมองเชิงทฤษฎีและพิจารณาว่ามีเพียงประเภทเดียวเราสามารถพูดได้อย่างมั่นใจว่าระบบประเภทของ Javascript ไม่มีแนวคิดเกี่ยวกับความหลากหลาย แต่เรามีการพิมพ์แบบเป็ดและการบังคับขู่เข็ญโดยนัย

แต่สิ่งนี้ไม่ควรทำให้เราคิดถึงประเภทต่างๆในโปรแกรมของเรา เนื่องจาก Javascript ไม่มีประเภทเราจึงจำเป็นต้องอนุมานระหว่างขั้นตอนการเข้ารหัส จิตใจของเราต้องยืนหยัดเพื่อคอมไพเลอร์ที่หายไปกล่าวคือทันทีที่เราดูโปรแกรมเราต้องจดจำไม่เพียง แต่อัลกอริทึมเท่านั้น แต่ยังรวมถึงประเภทพื้นฐาน (อาจจะเป็นหลายรูปแบบ) ด้วย ประเภทเหล่านี้จะช่วยให้เราสร้างโปรแกรมที่เชื่อถือได้และมีประสิทธิภาพมากขึ้น

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

ความหลากหลายของพาราเมตริก (aka generics)

ความหลากหลายเชิงพาราเมตริกกล่าวว่าประเภทต่างๆสามารถใช้แทนกันได้เนื่องจากประเภทไม่สำคัญเลย ฟังก์ชันที่กำหนดพารามิเตอร์อย่างน้อยหนึ่งพารามิเตอร์ของประเภทพหุนามพาราเมตริกจะต้องไม่รู้อะไรเกี่ยวกับอาร์กิวเมนต์ที่เกี่ยวข้อง แต่ปฏิบัติเหมือนกันทั้งหมดเนื่องจากสามารถนำไปใช้กับประเภทใดก็ได้ สิ่งนี้ค่อนข้าง จำกัด เนื่องจากฟังก์ชันดังกล่าวสามารถใช้ได้เฉพาะกับคุณสมบัติของอาร์กิวเมนต์ที่ไม่ได้เป็นส่วนหนึ่งของข้อมูลเท่านั้น:

// parametric polymorphic functions

const id = x => x;

id(1); // 1
id("foo"); // "foo"

const k = x => y => x;
const k_ = x => y => y;

k(1) ("foo"); // 1
k_(1) ("foo"); // "foo"

const append = x => xs => xs.concat([x]);

append(3) ([1, 2]); // [1, 2, 3]
append("c") (["a", "b"]); // ["a", "b", "c"]

ความหลากหลายของ Ad-hoc (aka overloading)

Ad-hoc polymorphism กล่าวว่าประเภทต่างๆมีความเท่าเทียมกันสำหรับวัตถุประสงค์เฉพาะเท่านั้น เพื่อให้เทียบเท่าในแง่นี้ประเภทต้องใช้ชุดของฟังก์ชันเฉพาะสำหรับวัตถุประสงค์นั้น ฟังก์ชันที่กำหนดพารามิเตอร์อย่างน้อยหนึ่งพารามิเตอร์ของชนิดโพลีมอร์ฟิค ad-hoc จำเป็นต้องทราบว่าชุดของฟังก์ชันใดที่เชื่อมโยงกับอาร์กิวเมนต์แต่ละตัว

ความหลากหลายของ Ad-hoc ทำให้ฟังก์ชันเข้ากันได้กับโดเมนประเภทใหญ่ ๆ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงจุดประสงค์ "map-over" และวิธีใช้ข้อ จำกัด นี้ แทนที่จะเป็นชุดของฟังก์ชันข้อ จำกัด "mappable" จะรวมเฉพาะmapฟังก์ชันเดียว:

// Option type
class Option {
  cata(pattern, option) {
    return pattern[option.constructor.name](option.x);
  }
  
  map(f, opt) {
    return this.cata({Some: x => new Some(f(x)), None: () => this}, opt);
  }
};

class Some extends Option {
  constructor(x) {
    super(x);
    this.x = x;
  }
};

class None extends Option {
  constructor() {
    super();
  }
};


// ad-hoc polymorphic function
const map = f => t => t.map(f, t);

// helper/data

const sqr = x => x * x;

const xs = [1, 2, 3];
const x = new Some(5);
const y = new None();

// application

console.log(
  map(sqr) (xs) // [1, 4, 9]
);

console.log(
  map(sqr) (x) // Some {x: 25}
);

console.log(
  map(sqr) (y) // None {}
);

ความแตกต่างของชนิดย่อย

เนื่องจากคำตอบอื่น ๆ ครอบคลุมความหลากหลายประเภทย่อยแล้วฉันจึงข้ามไป

ความหลากหลายของโครงสร้าง (aka strutrual subtyping)

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

const weight = {value: 90, foo: true};
const speed =  {value: 90, foo: false, bar: [1, 2, 3]};

น่าเสียดายที่speedถือเป็นประเภทย่อยweightและทันทีที่เราเปรียบเทียบvalueคุณสมบัติเราแทบจะเปรียบเทียบแอปเปิ้ลกับส้ม


1
แม้ว่าสิ่งนี้จะแม่นยำกว่าหลายประการ(และละเอียดถี่ถ้วนกว่า) มากกว่าคำตอบที่ยอมรับ แต่ก็ไม่มีความสามารถในการเข้าถึงเหมือนกัน: คำตอบนี้ถือว่าผู้ถามฉลาดเกินไปที่จะรบกวนคำถาม :)
Jared Smith

@JaredSmith ฉันพยายามต้มเรื่องให้เข้าใจง่ายขึ้นย่อหน้า แต่ยิ่งเจาะลึกก็ยิ่งซับซ้อน ฉันไม่เคยพบแหล่งที่ดีสำหรับความหลากหลายในภาษาที่ไม่ได้พิมพ์ดังนั้นฉันคิดว่าคำตอบนี้ยังคงมีค่า

การแก้ไขช่วยเพิ่มความสามารถในการเข้าถึงได้มาก สำหรับประโยชน์ของความหลากหลายในภาษาไดนามิกนั้นมีมากมาย แต่ฉันกำลังดิ้นรนที่จะนึกถึงตัวอย่างที่ดีใน JS เป็นตัวอย่างที่ดีกว่าจะวิธีมายากล ธ ที่ช่วยให้ผู้ใช้กำหนดประเภทที่จะทำงานร่วมกับฟังก์ชั่น polymorphic lenเช่น หรืออาจจะconjมาจาก clojure
Jared Smith

8

มันคืออะไร?

Poly = many, morphism = การเปลี่ยนแปลงรูปแบบหรือพฤติกรรม

ทำไมเราถึงต้องการ?

ในการเขียนโปรแกรมจะใช้เมื่อเราต้องการให้อินเทอร์เฟซของฟังก์ชัน (สมมติว่าฟังก์ชัน X) มีความยืดหยุ่นเพียงพอที่จะยอมรับประเภทหรือจำนวนพารามิเตอร์ต่างๆ นอกจากนี้จากการเปลี่ยนประเภทพารามิเตอร์หรือตัวเลขเราอาจต้องการให้ฟังก์ชัน X ทำงานแตกต่างกัน (morphism)

มันทำงานอย่างไร?

เราเขียนการใช้งานฟังก์ชัน X หลายรายการโดยที่การใช้งานแต่ละรายการยอมรับประเภทพารามิเตอร์หรือจำนวนพารามิเตอร์ที่แตกต่างกัน ตามประเภทหรือจำนวนพารามิเตอร์คอมไพเลอร์ (ที่รันไทม์) จะตัดสินใจว่าควรใช้ X ใดเมื่อ X ถูกเรียกใช้จากโค้ดบางตัว

ฉันจะบรรลุพฤติกรรมหลายรูปแบบนี้ในจาวาสคริปต์ได้อย่างไร

JS ไม่ใช่ภาษาพิมพ์ดังนั้นจึงไม่ได้หมายถึงการใช้แนวคิด OOP เช่นความหลากหลาย อย่างไรก็ตาม JS เวอร์ชันที่ใหม่กว่าในขณะนี้ได้รวมคลาสแล้วและมีความเป็นไปได้ที่โพลีโมสฟิสม์อาจเริ่มมีเหตุผลใน JS ด้วย คำตอบอื่น ๆ เป็นวิธีแก้ปัญหาที่น่าสนใจ


4

Polymorphism หมายถึงความสามารถในการเรียกใช้วิธีการเดียวกันกับวัตถุที่แตกต่างกันและแต่ละคนตอบสนองวัตถุในทางที่แตกต่างกันจะเรียกว่าสัณฐาน

    function Animal(sound){
    this.sound=sound;
    this.speak=function(){
    			return this.sound;
    	}
    }
//one method 
    function showInfo(obj){
    		console.log(obj.speak());
    }
//different objects
    var dog = new Animal("woof");
    var cat = new Animal("meow");
    var cow = new Animal("humbow");
//responds different ways
    showInfo(dog);
    showInfo(cat);
    showInfo(cow);


2

JavaScript เป็นภาษาที่ตีความไม่ใช่ภาษาที่คอมไพล์

เวลาคอมไพล์ Polymorhism (หรือ Static polymorphism) Compile time polymorphism ไม่มีอะไรนอกจากเมธอดที่โอเวอร์โหลดใน java, c ++

วิธีการโอเวอร์โหลดจึงไม่สามารถทำได้ในจาวาสคริปต์

แต่ความหลากหลายแบบไดนามิก (เวลาทำงาน) คือความหลากหลายที่มีอยู่ในเวลาทำงานดังนั้นวิธีการแทนที่จึงเป็นไปได้ในจาวาสคริปต์

อีกตัวอย่างหนึ่งคือ PHP

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