__proto__ แตกต่างจาก constructor.prototype อย่างไร


163
function Gadget(name, color)
{
   this.name = name;
   this.color = color;
}

Gadget.prototype.rating = 3

var newtoy = new Gadget("webcam", "black")

newtoy.constructor.prototype.constructor.prototype.constructor.prototype 

มันจะส่งคืนวัตถุที่มีการจัดอันดับ = 3

แต่ถ้าฉันทำต่อไปนี้:

newtoy.__proto__.__proto__.__proto__

nullห่วงโซ่จบลงด้วยการกลับมา

นอกจากนี้ใน Internet Explorer ฉันจะตรวจสอบโมฆะได้อย่างไรหากไม่มี__proto__คุณสมบัติ


30
นี้แผนภาพกราฟจะช่วยให้คุณเข้าใจความแตกต่างระหว่างต้นแบบและโปรโต คุณสามารถติดตามโปรโตโซ่จากวัตถุ newtoy แล้วคุณจะรู้ว่าทำไมProtoที่ 3 จาก newtoy เป็นโมฆะ
บิต

นอกจากนี้ที่ชัดเจนจากแผนภาพที่newtoy.prototypeไม่เท่ากับnewtoy.constructor.prototypeและดังนั้นจึงจะไม่ได้มีคุณสมบัติที่เรียกว่าnewtoy.constructor.prototype ratingในทำนองเดียวกันจะยังไม่ได้มีคุณสมบัติที่เรียกว่าnewtoy.constructor.prototype.constructor.property rating
บิต

พิมพ์ผิดในความคิดเห็นล่าสุด: ดังนั้นnewtoy.constructor.prototypeจะมีสถานที่ให้บริการที่เรียกว่าการให้คะแนน ในทำนองเดียวกันnewtoy.constructor.prototype.constructor.propertyก็จะมีคุณสมบัติที่เรียกว่าการให้คะแนน
บิต


1
@Royi Namir ฉันได้อัพโหลดjsVizบน github นี่คือเว็บไซต์สาธิต โปรดอย่ากังวลว่าโค้ดจริงนั้นไม่เปลี่ยนแปลง (และสกปรก) อย่างไร มันเป็นโครงการที่เก่ามากที่ฉันไม่ได้สัมผัสมาตลอด
บิต

คำตอบ:


210

ฉันพยายามห่อหัวของฉันรอบนี้เมื่อเร็ว ๆ นี้และในที่สุดก็เกิดขึ้นกับ "แผนที่" นี้ที่ฉันคิดว่าเพิงเต็มเรื่อง

http://i.stack.imgur.com/KFzI3.png ป้อนคำอธิบายรูปภาพที่นี่

ฉันรู้ว่าฉันไม่ใช่คนแรกที่สร้างสิ่งนี้ขึ้นมา แต่มันก็น่าสนใจกว่าถ้าคิดว่าการหามัน :-) อย่างไรก็ตามหลังจากนั้นฉันก็พบเช่นแผนภาพอื่นที่ฉันคิดว่าโดยพื้นฐานเดียวกันนี้:

เค้าโครงวัตถุ Javascript

สิ่งที่น่าประหลาดใจที่สุดสำหรับฉันคือการค้นพบว่าสิ่งนั้นObject.__proto__ชี้ไปที่Function.prototypeแทนที่จะเป็นObject.prototypeแต่ฉันแน่ใจว่ามีเหตุผลที่ดีสำหรับ :-)

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

Object.O1='';
Object.prototype.Op1='';

Function.F1 = '';
Function.prototype.Fp1 = '';

Cat = function(){};
Cat.C1 = '';
Cat.prototype.Cp1 = '';

mycat = new Cat();
o = {};

// EDITED: using console.dir now instead of console.log
console.dir(mycat);
console.dir(o);

2
@utsaina เด็ดมาก ชำระเงินการเป็นตัวแทนกราฟิกอื่นของรหัสที่ OP โพสต์ และฉันคิดว่าไดอะแกรมของเราอยู่ในข้อตกลงในแง่ของรายละเอียดทางเทคนิค
บิต

43
เหตุผลที่Object.__proto__ชี้ให้เห็นFunction.prototypeเพราะObject()ตัวมันเองเป็นฟังก์ชั่นพื้นฐานที่ทำให้วัตถุว่างเปล่า ดังนั้นจึงObject()เป็นฟังก์ชั่น คุณจะพบว่าทั้งหมดที่อื่น ๆ ที่สำคัญประเภทพื้นเมืองคุณสมบัติชี้ไปที่__proto__ , , , และทุกสืบทอดต้นแบบฟังก์ชั่น Function.prototypeObjectFunctionStringNumberArray
หมุน

@drodsou ลิงก์ที่ 2 ของคุณยอดเยี่ยม โปรดตรวจสอบตอนนี้ได้โปรด;) mollypages.org/misc/js.mpคำอธิบายที่ดี: D
abhisekp

@Swivel "ดังนั้น Object () เป็นฟังก์ชั่น" - คุณหมายถึงว่า Object เป็นฟังก์ชั่นหรือไม่? โดยไม่มี ()
giorgim

2
@GiorgiMoniava ถูกต้อง Objectตัวเองเป็นฟังก์ชั่น; ผลลัพธ์ของการดำเนินการ callable Object(เช่นค่าส่งคืนของการทำงานObject()) ไม่ใช่ฟังก์ชัน
หมุน

67

constructorเป็นคุณสมบัติที่กำหนดไว้ล่วงหน้า [[DontEnum]] ของวัตถุที่ชี้ไปตามprototypeคุณสมบัติของวัตถุฟังก์ชั่นและในขั้นต้นจะชี้ไปที่วัตถุฟังก์ชั่นของตัวเอง

__proto__ เทียบเท่ากับคุณสมบัติ [[Prototype]] ภายในของวัตถุเช่นต้นแบบจริง

เมื่อคุณสร้างวัตถุด้วยตัวnewดำเนินการคุณสมบัติ [[ต้นแบบ]] ภายในของมันจะถูกตั้งค่าเป็นวัตถุที่ชี้ไปตามprototypeคุณสมบัติของฟังก์ชันตัวสร้าง

นี่หมายความว่า.constructorจะประเมินค่า.__proto__.constructorเช่นฟังก์ชันตัวสร้างที่ใช้ในการสร้างวัตถุและเมื่อเราได้เรียนรู้แล้วprotoypeคุณสมบัติของฟังก์ชันนี้ใช้เพื่อตั้งค่า [[Prototype]] ของวัตถุ

มันตามมาซึ่ง.constructor.prototype.constructorเหมือนกับ.constructor(ตราบใดที่คุณสมบัติเหล่านี้ยังไม่ถูกเขียนทับ); ดูที่นี่สำหรับคำอธิบายโดยละเอียดเพิ่มเติม

ถ้า__proto__มีคุณสามารถเดินโซ่ต้นแบบที่แท้จริงของวัตถุ ไม่มีวิธีการทำเช่นนี้ใน ECMAScript3 ธรรมดาเพราะ JavaScript ไม่ได้ออกแบบมาสำหรับลำดับชั้นการสืบทอดที่ลึก


3
ลิงค์ 'นี่' นั้นเป็นมาตรฐานทองคำ ไปที่นั่นหากคุณต้องการคำอธิบายแบบเต็ม
Ricalsin

จับดีกับการ.constructor.prototypeผูกมัด ผมยังไม่ชัดเจนสำหรับผมในขณะที่ผมไม่เห็นว่าจะมีค่าเท่ากับ.constructor .__proto__.constructorซึ่งก็หมายถึงการขี่จักรยานระหว่างฟังก์ชั่นการสร้างและมันเป็นต้นแบบ
Johnny_D

30

Prototypal Inheritance ใน JavaScript ขึ้นอยู่กับ__proto__คุณสมบัติในแง่ที่ว่าวัตถุแต่ละอันกำลังสืบทอดเนื้อหาของวัตถุที่อ้างอิงโดย__proto__คุณสมบัติของมัน

prototypeคุณสมบัติพิเศษเฉพาะสำหรับFunctionวัตถุและเฉพาะเมื่อใช้newประกอบการที่จะเรียกFunctionว่าเป็นตัวสร้าง ในกรณีนี้ที่สร้างขึ้นของวัตถุจะถูกตั้งค่าของตัวสร้าง__proto__Function.prototype

ซึ่งหมายความว่าการเพิ่มเพื่อFunction.prototypeจะสะท้อนให้เห็นโดยอัตโนมัติบนวัตถุทั้งหมดที่มีอยู่ในการอ้างอิง__proto__Function.prototype

การแทนที่คอนสตรัคเตอร์Function.prototypeด้วยวัตถุอื่นจะไม่อัปเดต__proto__คุณสมบัติสำหรับวัตถุใด ๆ ที่มีอยู่แล้ว

โปรดทราบว่า__proto__ไม่ควรเข้าถึงคุณสมบัติโดยตรงควรใช้Object.getPrototypeOf (object)แทน

เพื่อตอบคำถามแรกฉันได้สร้างไดอะแกรมของ bespoke __proto__และprototypeข้อมูลอ้างอิงโชคไม่ดีที่ stackoverflow ไม่อนุญาตให้ฉันเพิ่มรูปภาพที่มี "ชื่อเสียงน้อยกว่า 10" บางทีเวลาอื่น

[แก้ไข] ตัวเลขใช้[[Prototype]]แทน__proto__เนื่องจากเป็นวิธีที่ข้อมูลจำเพาะ ECMAScript อ้างถึงวัตถุภายใน ฉันหวังว่าคุณจะสามารถเข้าใจทุกสิ่งได้

นี่คือคำแนะนำที่จะช่วยให้คุณเข้าใจรูปร่าง:

red    = JavaScript Function constructor and its prototype
violet = JavaScript Object constructor and its prototype
green  = user-created objects
         (first created using Object constructor or object literal {},
          second using user-defined constructor function)
blue   = user-defined function and its prototype
         (when you create a function, two objects are created in memory:
          the function and its prototype)

โปรดทราบว่าconstructorคุณสมบัตินี้ไม่มีอยู่ในวัตถุที่สร้าง แต่สืบทอดมาจากต้นแบบ

ป้อนคำอธิบายรูปภาพที่นี่


@xorcus คุณช่วยอธิบายสิ่งนี้ได้ไหม: new MyFunction()สร้างอินสแตนซ์ของวัตถุที่มัน__proto__ควรอ้างถึงต้นแบบ ctor ของมันซึ่งก็คือMyFunction.prototype.ทำไมถึงMyFunction.prototype.__proto__อ้างถึงObject.prototype? มันควร referene (เช่นตัวอย่างแรกของฉัน) ไปยังต้นแบบของ ctor ซึ่งก็คือMyFunction.prototype(สังเกตว่าMyFunction.prototypeเป็นพื้นผิวMyfunction)
Royi Namir

@Royi Namir: MyFunction.prototype .__ proto__ อ้างถึง Object.prototype เพราะ MyFunction.prototype เป็นวัตถุ Object.prototype สืบทอดมาจากวัตถุทั้งหมด (โดยปกตินั่นคือจุดที่โซ่ต้นแบบของการสืบทอดสิ้นสุดลง) ฉันไม่เห็นด้วยที่ MyFunction.prototype เป็นตัวอย่างของ MyFunction obj instanceof MyFunction <=> MyFunction.prototype.isPrototypeOf (obj) <=> MyFunction.prototype มีอยู่ในห่วงโซ่ต้นแบบ obj นั่นไม่ใช่กรณีของวัตถุ
MyFunction.prototype

14

ObjectคืออีฟและFunctionอาดัมอาดัม ( Function) ใช้กระดูกของเขา ( Function.prototype) เพื่อสร้างเอวา ( Object) ใครเป็นผู้สร้างอดัม ( Function) - ผู้ประดิษฐ์ภาษา JavaScript :-)

ตามคำตอบของ utsaina ฉันต้องการเพิ่มข้อมูลที่มีประโยชน์มากขึ้น

สิ่งที่น่าประหลาดใจที่สุดสำหรับฉันคือการค้นพบว่าสิ่งนั้นObject.__proto__ ชี้ไปที่Function.prototypeแทนที่จะเป็นObject.prototypeแต่ฉันแน่ใจว่ามีเหตุผลที่ดีสำหรับ :-)

มันไม่ควรจะเป็น ไม่ควรชี้ไปที่Object.__proto__ Object.prototypeแต่ตัวอย่างของObject o, ควรชี้ไปที่o.__proto__Object.prototype

(ยกโทษให้ฉันสำหรับการใช้คำclassและinstanceใน JavaScript แต่คุณรู้ :-)

ผมคิดว่าการเรียนObjectของตัวเองเป็นตัวอย่างของที่ว่าทำไมFunction Object.__proto__ === Function.prototypeดังนั้น: ObjectคืออีฟและFunctionอาดัมอาดัม ( Function) ใช้กระดูกของเขา ( Function.prototype) เพื่อสร้างเอวา ( Object)

ยิ่งกว่านั้นคลาสFunctionเองก็เป็นตัวอย่างของFunctionตัวเองนั่นคือFunction.__proto__ === Function.prototypeสาเหตุFunction === Function.constructor

เพิ่มเติมนอกจากนี้ระดับปกติCatเป็นตัวอย่างของที่เป็นFunctionCat.__proto__ === Function.prototype

เหตุผลดังกล่าวข้างต้นคือเมื่อเราสร้างชั้นใน JavaScript Functionที่จริงเรามีเพียงแค่การสร้างฟังก์ชั่นซึ่งควรจะเป็นตัวอย่างของ ObjectและFunctionเป็นเพียงพิเศษ แต่พวกเขายังคงเรียนในขณะที่Catเป็นชั้นเรียนปกติ

ตามปัจจัยในเครื่องมือ Google Chrome JavaScript มีดังต่อไปนี้ 4:

  • Function.prototype
  • Function.__proto__
  • Object.__proto__
  • Cat.__proto__

พวกเขาทั้งหมด===(เท่ากันอย่างแน่นอน) กับอีก 3 และค่าของพวกเขาคือfunction Empty() {}

> Function.prototype
  function Empty() {}
> Function.__proto__
  function Empty() {}
> Object.__proto__
  function Empty() {}
> Cat.__proto__
  function Empty() {}
> Function.prototype === Function.__proto__
  true
> Function.__proto__ === Object.__proto__
  true
> Object.__proto__ === Cat.__proto__
  true

ตกลง. แล้วใครเป็นคนสร้างความพิเศษfunction Empty() {} ( Function.prototype)? คิดเกี่ยวกับมัน :-)


เห็นด้วยกับสิ่งนั้นยกเว้นสิ่งสุดท้าย: function Empty() {}คุณหมายถึงอะไรเท่ากับ Function.prototype และอื่น ๆ รหัสอะไรที่คุณใช้ในคอนโซลโครเมี่ยม
drodsou

2
ฉันแก้ไขสิ่งสุดท้ายที่คุณชี้ให้เห็น คุณค่าของพวกเขาอยู่function Empty() {}ใน Google Chrome ฉันยังเพิ่มคอนโซลเอาต์พุต
Peter Lee

ฟังก์ชั่นทั้งหมดเป็นอินสแตนซ์ของฟังก์ชั่นและดังนั้นฟังก์ชั่นทั้งหมดสืบทอด ( _ _proto_ _) จาก Function.prototype มันง่ายอย่างนั้น :)
xorcus

ขออภัยสำหรับความคิดเห็นในหัวข้อเก่า แต่พวกเขาถูกสร้างขึ้นโดยนักประดิษฐ์ของภาษา?
Patel Parth

6

ฉันไม่รู้จริง ๆ ว่าทำไมคนถึงไม่แก้ไขคุณเกี่ยวกับปัญหาที่แท้จริงในความเข้าใจของคุณ

สิ่งนี้จะช่วยให้คุณสังเกตเห็นปัญหาได้ง่ายขึ้นมาก

ดังนั้นเรามาดูสิ่งที่เกิดขึ้น:

var newtoy = new Gadget("webcam", "black")

newtoy 
  .constructor //newtoy's constructor function is newtoy ( the function itself)
    .prototype // the function has a prototype property.( all functions has)
      .constructor // constructor here is a **property** (why ? becuase you just did `prototype.constructor`... see the dot ? )  ! it is not(!) the constructor function  !!! this is where your mess begins. it points back to the constructor function itself ( newtoy function)
         .prototype // so again we are at line 3 of this code snippet
            .constructor //same as line 4 ...
                .prototype 
                 rating = 3

เยี่ยมมากเลยมาดูกันดีกว่า __proto__

ก่อนหน้านั้นโปรดจำไว้ 2 ข้อเกี่ยวกับ__proto__ :

  1. เมื่อคุณสร้างวัตถุที่มีnewโอเปอเรเตอร์ภายใน[[Prototype]]/ proto__คุณสมบัติจะถูกตั้งค่าเป็นprototypeคุณสมบัติ (1) ของมันconstructor functionหรือ "ผู้สร้าง" หากคุณต้องการ

  2. ฮาร์ดรหัสภายใน JS -: เป็นObject.prototype.__proto__null

ลองอ้างถึง 2 จุดเหล่านี้ว่า " bill"

newtoy
     .__proto__ // When `newtoy` was created , Js put __proto__'s value equal to the value of the cunstructor's prototype value. which is `Gadget.prototype`.
       .__proto__ // Ok so now our starting point is `Gadget.prototype`. so  regarding "bill" who is the constructor function now? watch out !! it's a simple object ! a regular object ! prototype is a regular object!! so who is the constructor function of that object ? Right , it's the `function Object(){...}`.  Ok .( continuing "bill" ) does it has a `prototype` property ? sure. all function has. it's `Object.prototype`. just remember that when Gadget.prototype was created , it's internal `__proto__` was refered to `Object.prototype` becuase as "bill" says :"..will be set to the `prototype` property of   its `constructor function`"
          .__proto__ // Ok so now our satrting point is `Object.prototype`. STOP. read bullet 2.Object.prototype.__proto__ is null by definition. when Object.prototype ( as an object) was created , they SET THE __PROTO__ AS NULL HARDCODED

ดีขึ้นหรือไม่


2

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


1
ฉันคิดว่าคุณหมายถึง__proto__สถานที่ให้บริการ
demisx

ใช่. ฉันหมายถึงคุณสมบัติโปรโตของวัตถุ ฉันหวังว่าข้อมูลนี้มีประโยชน์
Apoorv Nag

2

หากตัวเลขทั้งหมดเหล่านั้นท่วมท้นลองดูความหมายของคุณสมบัติ

STH.prototype

เมื่อสร้างฟังก์ชั่นใหม่มีวัตถุว่างเปล่าที่ถูกสร้างขึ้นในแบบขนานและเชื่อมโยงกับฟังก์ชั่นที่มี[[Prototype]]ห่วงโซ่ ในการเข้าถึงวัตถุนี้เราใช้ prototypeคุณสมบัติของฟังก์ชั่น

function Gadget() {}
// in background, new object has been created
// we can access it with Gadget.prototype
// it looks somewhat like {constructor: Gadget}

โปรดจำไว้ว่าprototypeคุณสมบัตินี้ใช้งานได้กับฟังก์ชั่นเท่านั้น

STH.constructor

ต้นแบบวัตถุดังกล่าวข้างต้นมีคุณสมบัติไม่มียกเว้นหนึ่ง constructor- คุณสมบัตินี้แสดงถึงฟังก์ชั่นที่สร้างวัตถุต้นแบบ

var toy = new Gadget();

เมื่อสร้าง Gadgetฟังก์ชั่นเราสร้างวัตถุเช่น{constructor: Gadget}กัน - มันไม่เหมือนGadget.prototypeกัน ตามที่constructorอ้างถึงฟังก์ชั่นที่สร้างวัตถุต้นแบบtoy.constructorหมายถึงGadgetฟังก์ชั่น เราเขียนtoy.constructor.prototypeและเราได้รับ{constructor: Gadget}อีกครั้ง

ดังนั้นจึงมีวงจรอุบาทว์: คุณสามารถใช้toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototypeและจะเป็นGadget.prototypeเสมอ

toy
.constructor    // Gadget
.prototype    // {constructor: Gadget}
.constructor    // Gadget
.prototype    // {constructor: Gadget}
// ...

STH .__ proto__

ในขณะที่ prototypeเป็นเฉพาะอสังหาริมทรัพย์สำหรับฟังก์ชั่นที่มีอยู่สำหรับวัตถุทั้งหมดในขณะที่มันวางใน__proto__ Object.prototypeมันหมายถึงต้นแบบของฟังก์ชั่นที่สามารถสร้างวัตถุ

[].__proto__ === Array.prototype
// true

({}).__proto === Object.prototype
// true

ที่นี่คือtoy.__proto__ Gadget.prototypeในฐานะที่Gadget.prototypeเป็นวัตถุ ( {}) และวัตถุที่สร้างขึ้นด้วยObjectฟังก์ชั่น (ดูตัวอย่างข้างต้น) Object.prototypeที่เราได้รับ นี้เป็นวัตถุที่สูงขึ้นใน JavaScript และสามารถบ่งบอกถึง__proto__null

toy
.__proto__    // Gadget.prototype (object looking like {constructor: Gadget})
.__proto__    // Object.prototype (topmost object in JS)
.__proto__    // null - Object.prototype is the end of any chain

0

คำตอบสั้น ๆ : __proto__เป็นการอ้างอิงถึงprototypeคุณสมบัติของตัวสร้างที่สร้างวัตถุ

วัตถุใน JavaScript

วัตถุ JavaScript เป็นชนิดในตัวสำหรับคอลเลกชันคุณสมบัติที่เป็นศูนย์หรือมากกว่า คุณสมบัติคือภาชนะที่เก็บวัตถุอื่น ๆ ค่าดั้งเดิมหรือฟังก์ชั่น

ตัวสร้างใน JavaScript

ฟังก์ชั่นเป็นวัตถุปกติ (ซึ่งนำมาใช้[[Call]]ในข้อกำหนด ECMA-262) ด้วยความสามารถเพิ่มเติมของการโทรออกได้ แต่มีบทบาทอื่นใน JavaScript: พวกเขากลายเป็นตัวสร้าง ( โรงงานสำหรับวัตถุ) หากเรียกใช้ผ่านnewดำเนินการ ตัวสร้างเป็นแบบอะนาล็อกคร่าวๆกับคลาสในภาษาอื่น

ทุกฟังก์ชั่นจาวาสคริปต์เป็นตัวอย่างของFunctionฟังก์ชั่นวัตถุในตัวที่มีคุณสมบัติพิเศษชื่อที่prototypeใช้ในการใช้การสืบทอดตามคุณสมบัติต้นแบบและคุณสมบัติที่ใช้ร่วมกัน ทุกวัตถุที่สร้างโดยฟังก์ชั่นคอนสตรัคเตอร์มีการอ้างอิงโดยนัย (เรียกว่าต้นแบบหรือ__proto__) กับค่าของคอนสตรัคprototypeเตอร์

นวกรรมิกprototypeเป็นแบบพิมพ์เขียวสำหรับการสร้างวัตถุเนื่องจากทุกวัตถุที่สร้างโดยนวกรรมิกได้รับการอ้างอิงถึงprototypeสำหรับการสร้างวัตถุตั้งแต่ทุกวัตถุที่สร้างขึ้นโดยคอนสตรัคสืบทอดการอ้างอิงถึงมัน

โซ่ต้นแบบ

ระบุวัตถุต้นแบบที่ผ่านคุณสมบัติภายในหรือ[[Prototype]] __proto__ความสัมพันธ์ต้นแบบระหว่างวัตถุสองชิ้นนั้นเกี่ยวกับการสืบทอด: ทุกวัตถุสามารถมีวัตถุอื่นเป็นต้นแบบ ต้นแบบอาจเป็นnullค่า

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

ดูภาพนี้ (แยกจากบล็อกนี้):

proto.jpg

เมื่อใดก็ตามที่คุณพยายามเข้าถึงทรัพย์สินในวัตถุ JavaScript เริ่มต้นการค้นหาสำหรับมันในวัตถุที่และยังคงมีต้นแบบของต้นแบบต้นแบบและอื่น ๆ จนทรัพย์สินที่จะพบหรือถ้าถือค่า__proto__null

การสืบทอดประเภทนี้โดยใช้ลูกโซ่ต้นแบบมักถูกเรียกว่าการมอบหมายเพื่อหลีกเลี่ยงความสับสนกับภาษาอื่น ๆ โดยใช้คลาสลูกโซ่

วัตถุเกือบทั้งหมดเป็นอินสแตนซ์ของObjectเนื่องจากObject.prototypeอยู่ในห่วงโซ่ต้นแบบของพวกเขา แต่Object.prototypeไม่ใช่ตัวอย่างObjectเนื่องจากObject.prototype.__proto__เก็บค่าnullไว้

คุณยังสามารถสร้างวัตถุด้วยnullต้นแบบดังนี้:

var dict = Object.create(null);

วัตถุดังกล่าวเป็นแผนที่ที่ดีกว่า (พจนานุกรม) มากกว่าวัตถุที่แท้จริงซึ่งเป็นเหตุผลที่ทำแบบนี้บางครั้งเรียกว่าDictรูปแบบ ( Dictพจนานุกรม)

หมายเหตุ: วัตถุที่สร้างขึ้นโดยใช้ตัวอักษร{}เป็นกรณีของObjectตั้งแต่มีการอ้างอิงถึง({}).__proto__Object.prototype


โปรดอ้างอิงแหล่งที่มาของคำพูดและสิ่งประดิษฐ์ที่คุณใช้ ภาพดูเหมือนจะมาจากgiamir.com/pseudoclasses-and-prototypal-inheritance-in-JSคุณมีลิขสิทธิ์หรือไม่
Bergi

@Bergi ฉันอ้างถึงที่มาของภาพ คำพูดส่วนใหญ่ที่ฉันใช้นั้นถูกดึงมาจากมาตรฐาน JS หรือ MDN
eigenslacker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.