"ส่วนตัว" และ "สาธารณะ" ในองค์ประกอบเชิงมุม


120

ถ้าฉันไม่ได้เพิ่มส่วนตัวก่อนfoo, loadBarและtextผมเชื่อว่าพวกเขาจะมีประชาชนไปโดยปริยาย

export class RandomComponent {
  @Input() foo: string;
  @Output() loadBar = new EventEmitter();
  text: string;
}

มีกรณีการใช้งานเมื่ออยู่publicในส่วนประกอบหรือไม่?

ด้วยเหตุผลด้านการห่อหุ้ม / ความปลอดภัยฉันควรเพิ่มprivateสิ่งเหล่านี้ทั้งหมดไว้ด้านล่างหรือไม่?

export class RandomComponent {
  @Input() private foo: string;
  @Output() private loadBar = new EventEmitter();
  private text: string;
}

ขอบคุณ


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

คำตอบ:


202

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

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

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

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

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

ดังนั้นคำตอบของฉันสำหรับคำถามของคุณ:

ฉันควรเพิ่มความเป็นส่วนตัวสำหรับทุกคนเช่นด้านล่างนี้หรือไม่

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


5
ขอบคุณสำหรับคำอธิบาย แต่บางทีฉันเข้าใจผิด: ฉันเข้าใจว่าคุณสมบัติและวิธีการของเวลาส่วนใหญ่ต้องเป็นแบบส่วนตัว (= "สำหรับส่วนประกอบนี้ใช้เท่านั้น") ดังนั้นคำตอบควรเป็น "ใช่โดยค่าเริ่มต้นตราบใดที่ผู้ชายไม่จำเป็นต้องเปิดเผยคุณสมบัติ / วิธีการสู่ภายนอก" ไม่? ทำไมสรุปคำอธิบายของคุณโดยตอบว่า "ไม่" (ซึ่งฟังดูเหมือน "ไม่เคย")
M'sieur Toph '21

1
ฉันเป็นแบบฝึกหัดเชิงมุม 2 สีแดงและฉันไม่ทราบว่าควรใช้สาธารณะเมื่อใด มีตัวแปรมากมายสำหรับการสื่อสารของคอมโพเนนต์: angular.io/docs/ts/latest/cookbook/…เราน่าจะใช้ public สำหรับคุณสมบัติและวิธีการที่กำหนดผ่าน Input Output เท่านั้น แต่ฉันไม่แน่ใจ.
Ruslan Borovok

ฉันมักจะต้องใช้ 'สาธารณะ' เมื่อฉันประกาศคุณสมบัติในตัวสร้างที่ไม่ได้ใช้ในคลาส แต่ใช้ภายนอก (เช่นในเทมเพลตหรือส่วนประกอบอื่น)
tuliomarchetto

18

@drewmoore ให้คำตอบที่ดีในเรื่องส่วนตัว / สาธารณะนั้นขึ้นอยู่กับเจตนา แต่มีอีกสองสามสิ่งที่ควรพิจารณาเมื่อใช้ค่าส่วนตัวที่ฉีดเข้าไป:

  • ทั้ง typescript ( noUnusedLocals ) และ tslint ( no-unused-variable ) จะรายงานข้อผิดพลาดหากคุณใช้@Import() private fooหรือconstructor(private foo) {}และใช้เฉพาะfooในเทมเพลตของคุณเท่านั้น
  • ทอท. เคยชิน :

หากเราต้องการปล่อย TypeScript เป็นผลลัพธ์ของกระบวนการคอมไพล์ AoT เราต้องแน่ใจว่าเราเข้าถึงเฉพาะฟิลด์สาธารณะในเทมเพลตของส่วนประกอบของเรา **


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

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