ปิดครั้งแรกจำได้ว่า JavaScript เป็นหลักภาษา prototypalมากกว่าภาษาระดับตาม 1 Foo
ไม่ใช่คลาส แต่เป็นฟังก์ชันซึ่งเป็นวัตถุ คุณสามารถยกตัวอย่างวัตถุจากฟังก์ชั่นนั้นโดยใช้new
คำสำคัญซึ่งจะช่วยให้คุณสร้างสิ่งที่คล้ายกับคลาสในภาษา OOP มาตรฐาน
ฉันขอแนะนำให้ละเว้น__proto__
เวลาส่วนใหญ่เนื่องจากมีการรองรับเบราว์เซอร์ที่ไม่ดีและให้ความสำคัญกับการเรียนรู้เกี่ยวกับวิธีการprototype
ทำงาน
หากคุณมีอินสแตนซ์ของวัตถุที่สร้างขึ้นจากฟังก์ชัน2และคุณเข้าถึงหนึ่งในสมาชิกของมัน (วิธีการคุณลักษณะคุณสมบัติค่าคงที่ ฯลฯ ) ในทางใด ๆ การเข้าถึงจะไหลลงลำดับชั้นต้นแบบจนกว่ามันจะ (a) ค้นหา สมาชิกหรือ (b) ไม่พบต้นแบบอื่น
ลำดับชั้นเริ่มต้นบนวัตถุที่ถูกเรียกแล้วค้นหาวัตถุต้นแบบ หากวัตถุต้นแบบมีต้นแบบมันจะทำซ้ำถ้าไม่มีต้นแบบundefined
จะถูกส่งกลับ
ตัวอย่างเช่น:
foo = {bar: 'baz'};
console.log(foo.bar); // logs "baz"
foo = {};
console.log(foo.bar); // logs undefined
function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
console.log(f.bar);
// logs "baz" because the object f doesn't have an attribute "bar"
// so it checks the prototype
f.bar = 'buzz';
console.log( f.bar ); // logs "buzz" because f has an attribute "bar" set
ดูเหมือนว่าคุณอย่างน้อยคุณก็เข้าใจชิ้นส่วน "พื้นฐาน" เหล่านี้อยู่แล้ว แต่ฉันต้องทำให้ชัดเจนเพื่อให้แน่ใจ
ใน JavaScript ทุกอย่างเป็นวัตถุ3
ทุกอย่างเป็นวัตถุ
function Foo(){}
ไม่เพียงแค่กำหนดฟังก์ชั่นใหม่ แต่ยังกำหนดฟังก์ชั่นวัตถุใหม่ที่สามารถเข้าถึงได้โดยใช้ Foo
แต่กำหนดฟังก์ชั่นใหม่ที่จะกำหนดวัตถุที่ฟังก์ชั่นใหม่ที่สามารถเข้าถึงได้โดยใช้
นี่คือเหตุผลที่คุณสามารถเข้าถึงFoo
's Foo.prototype
ต้นแบบ
สิ่งที่คุณสามารถทำได้คือตั้งค่าฟังก์ชั่นเพิ่มเติมในFoo
:
Foo.talk = function () {
alert('hello world!');
};
ฟังก์ชั่นใหม่นี้สามารถเข้าถึงได้โดยใช้:
Foo.talk();
ฉันหวังว่าตอนนี้คุณกำลังสังเกตเห็นความคล้ายคลึงกันระหว่างฟังก์ชั่นในฟังก์ชั่นวัตถุและวิธีการคงที่
คิดว่าf = new Foo();
เป็นการสร้างอินสแตนซ์ของคลาสเช่นFoo.prototype.bar = function(){...}
เดียวกับการกำหนดวิธีการที่ใช้ร่วมกันสำหรับชั้นเรียนและFoo.baz = function(){...}
การกำหนดวิธีการคงที่สาธารณะสำหรับชั้นเรียน
ECMAScript 2015 เปิดตัวน้ำตาลซินแทกติกที่หลากหลายสำหรับการประกาศประเภทเหล่านี้เพื่อให้ง่ายต่อการนำไปใช้และง่ายต่อการอ่าน ตัวอย่างก่อนหน้านี้สามารถเขียนเป็น:
class Foo {
bar() {...}
static baz() {...}
}
ซึ่งอนุญาตให้bar
เรียกว่า:
const f = new Foo()
f.bar()
และbaz
ถูกเรียกว่า:
Foo.baz()
1: class
เป็น "คำสงวนในอนาคต" ในข้อกำหนด ECMAScript 5แต่ ES6 แนะนำความสามารถในการกำหนดคลาสโดยใช้class
คำหลัก
2: โดยพื้นฐานแล้วคลาสอินสแตนซ์ที่สร้างโดยนวกรรมิก แต่มีความแตกต่างที่เหมาะสมหลายอย่างที่ฉันไม่ต้องการให้คุณเข้าใจผิด
3: ค่าดั้งเดิม - ซึ่งรวมถึงundefined
, null
บูลีน, ตัวเลขและสตริง - ไม่ใช่วัตถุในทางเทคนิคเพราะเป็นภาษาที่ใช้ในระดับต่ำ บูลีน, ตัวเลขและสายอักขระยังคงมีปฏิสัมพันธ์กับห่วงโซ่ต้นแบบราวกับว่าพวกมันเป็นวัตถุดังนั้นสำหรับจุดประสงค์ของคำตอบนี้มันง่ายกว่าที่จะพิจารณาว่าพวกเขา "วัตถุ" แม้ว่าพวกเขาจะไม่ได้ค่อนข้าง
Foo.talk = function ...