ขีดล่างนำหน้าสำหรับชื่อคุณสมบัติและเมธอดใน JavaScript


241

คำนำหน้าขีดล่างใน JavaScript มีเพียงแบบแผนเท่านั้นตัวอย่างเช่นในวิธีการเรียนแบบส่วนตัวของ Python คืออะไร?

จากเอกสาร 2.7 Python:

ตัวแปรอินสแตนซ์“ ส่วนตัว” ที่ไม่สามารถเข้าถึงได้ยกเว้นจากภายในวัตถุไม่มีอยู่ใน Python อย่างไรก็ตามมีการประชุมที่ตามด้วยรหัส Python ส่วนใหญ่: ชื่อที่นำหน้าด้วยเครื่องหมายขีดล่าง (เช่น _spam) ควรได้รับการปฏิบัติเสมือนเป็นส่วนที่ไม่เปิดเผยต่อสาธารณะของ API (ไม่ว่าจะเป็นฟังก์ชันวิธีการหรือสมาชิกข้อมูล) .

สิ่งนี้ใช้กับ JavaScript ได้หรือไม่

ยกตัวอย่างโค้ด JavaScript นี้:

function AltTabPopup() {
    this._init();
}

AltTabPopup.prototype = {
    _init : function() {
        ...
    }
}

นอกจากนี้ยังใช้ตัวแปรนำหน้าขีดล่าง

    ...
    this._currentApp = 0;
    this._currentWindow = -1;
    this._thumbnailTimeoutId = 0;
    this._motionTimeoutId = 0;
    ...

การประชุมเท่านั้น? หรือมีมากขึ้นหลังคำนำหน้าขีดล่าง?


ฉันยอมรับคำถามของฉันค่อนข้างคล้ายกับคำถามนี้แต่ก็ไม่ได้ทำให้ใครฉลาดขึ้นเกี่ยวกับความสำคัญของคำนำหน้าขีดล่างใน JavaScript


คำตอบ:


33

ยินดีต้อนรับสู่ 2019!

ดูเหมือนว่าข้อเสนอเพื่อขยายไวยากรณ์คลาสเพื่อให้#สามารถยอมรับตัวแปรนำหน้าเป็นส่วนตัวได้ Chrome 74 มาพร้อมกับการสนับสนุนนี้

_ คำนำหน้าชื่อตัวแปรถือเป็นส่วนตัวโดยการประชุม แต่ยังคงเป็นสาธารณะ

ไวยากรณ์นี้พยายามที่จะเป็นทั้งสั้นและง่าย แต่มันค่อนข้างแตกต่างจากภาษาการเขียนโปรแกรมอื่น ๆ

ทำไม sigil # ถูกเลือกในทุกจุดรหัส Unicode?

  • @ เป็นรายการโปรดเริ่มต้น แต่ถูกนำไปโดยนักตกแต่ง TC39 พิจารณาการสลับสับเปลี่ยนนักตกแต่งและกลุ่มรัฐส่วนตัว แต่คณะกรรมการได้ตัดสินใจเลื่อนการใช้งานของผู้ใช้ transpiler ที่มีอยู่เดิม
  • _ จะทำให้เกิดปัญหาความเข้ากันได้กับรหัส JavaScript ที่มีอยู่ซึ่งอนุญาตให้ _ เมื่อเริ่มต้นตัวระบุหรือชื่อคุณสมบัติ (สาธารณะ) เป็นเวลานาน

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

ดูhttps://caniuse.com/#feat=mdn-javascript_classes_private_class_fields


257

นั่นเป็นเพียงการประชุม ภาษา Javascript ไม่มีความหมายพิเศษใด ๆ กับตัวระบุที่ขึ้นต้นด้วยอักขระขีดล่าง

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


4
ได้. แม้ว่าภาษานั้นจะไม่ "สนับสนุน" แต่ก็เป็นเรื่องที่มีประโยชน์มาก
Juho Vepsäläinen

ปัญหาที่ร้ายแรง jsfiddle.net/VmFSRอย่างที่คุณเห็นนั่นคือชื่อที่สร้างคุณค่านั้นสามารถเข้าถึงได้โดยการเติมค่าใหม่ที่สร้างไว้ล่วงหน้าโดยใช้_ฉันอยากรู้ว่าเกิดอะไรขึ้น! ทำไมมันไม่this.nameแทน
มูฮัมหมัดอูเมอ

1
@ Muhammad Umer ฉันไม่แน่ใจว่าฉันเข้าใจความคิดเห็นของคุณ console.log(someone._name = "Jean Dupont");ทำงานได้ดีconsole.log(someone.name);และทั้งสองกำหนดและประเมินสมาชิกขีดล่างนำหน้าหลังทรัพย์สิน อย่างที่คุณเห็นมีไม่มีการห่อหุ้มรับประกันผ่านขีดล่าง :)
Frédéric Hamidi

3
โดยค่าเริ่มต้น Visual Studio พยายามช่วยคุณเคารพสิ่งนี้ เอ็นจิ้น javascript IntelliSense แสดงคุณสมบัติ "ส่วนตัว" จากภายในวัตถุเมื่อใช้ตัวแปร "this" แต่เมื่อถูกเรียกจากภายนอกมันจะซ่อนคุณสมบัติที่ไม่ได้เน้นทั้งหมด
foxontherock

1
@Karuhanga เขาตอบกลับในปี 2010 - แน่นอนว่าสิ่งต่าง ๆ มีการเปลี่ยนแปลงใน 10 ปี
Kenny Meyer

99

JavaScript สนับสนุนการห่อหุ้มผ่านวิธีการที่เกี่ยวข้องกับการซ่อนสมาชิกในการปิด (Crockford) ที่กล่าวว่าบางครั้งก็ยุ่งยากและการประชุมแบบขีดล่างเป็นวิธีที่ดีที่จะใช้กับสิ่งที่เป็นส่วนตัว แต่คุณไม่จำเป็นต้องซ่อนตัว


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

3
การซ่อนสมาชิกในการปิดบางครั้งอาจเป็นอุปสรรคต่อการทดสอบ ลองดูบทความนี้: พอสมควรดีดอท
คอม 2011/10/50/Writing-Testable-JavaScript

4
@ Jason - แค่อยากรู้ว่าทำไมคุณถึงเน้นการประชุมที่ไม่ดี?
Tamás Pap

5
@TamasPap - เหตุผลสองสามข้อ แต่เป็นเพียงตัวเลือกของฉัน: 1) ไม้ยันรักแร้ที่จะบังคับให้ JS เป็นภาษาอื่น ๆ 2) ถ้าเข้าถึงได้มันจะถูกใช้ ขีดเส้นใต้สามารถทิ้งขยะและโน้มน้าวโค้ดภายนอก 3) สับสนกับโปรแกรมเมอร์ JS ใหม่
Jason

9
แม้จะมีการปิดก็ยังเป็นไปได้ในทางเทคนิคในการเข้าถึงตัวแปรที่เรียกว่า "ส่วนตัว" _convention อย่างน้อยก็ทำให้ผู้รู้รู้ว่าต้องทำเช่นนั้นด้วยความเสี่ยงของตัวเอง (หรืออะไรทำนองนั้น)
sarink

14

JSDoc 3 ช่วยให้คุณสามารถใส่คำอธิบายประกอบการทำงานของคุณด้วย@access private(ก่อนหน้านี้@privateแท็ก) ซึ่งเป็นประโยชน์สำหรับการเผยแพร่ความตั้งใจของคุณไปยังผู้พัฒนารายอื่น - http://usejsdoc.org/tags-access.html


10

"แบบแผนเท่านั้นหรือมีอีกหลังคำนำหน้าขีดล่างหรือไม่"

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

ตัวอย่าง (จาก https://github.com/mmikowski/urianchor ):

$.uriAnchor.setAnchor({
  page   : 'profile',
  _page  : {
    uname   : 'wendy',
    online  : 'today'
  }
});

ตัวยึด URI ในช่องค้นหาของเบราว์เซอร์เปลี่ยนเป็น:

\#!page=profile:uname,wendy|online,today

นี่คือการประชุมที่ใช้เพื่อผลักดันสถานะแอปพลิเคชันตามการเปลี่ยนแปลงแฮช


8

import/exportกำลังทำงานกับ ES6 ฉันยังคงมีแนวโน้มที่จะนำหน้าฟังก์ชั่นไม่ส่งออกด้วย_ถ้าฟังก์ชั่นส่วนใหญ่ของฉันถูกส่งออก

หากคุณส่งออกเฉพาะคลาส (เช่นในโครงการเชิงมุม) ก็ไม่จำเป็นเลย

export class MyOpenClass{

    open(){
         doStuff()
         this._privateStuff()
         return close();
    }

    _privateStuff() { /* _ only as a convention */} 

}

function close(){ /*... this is really private... */ }

ฉันไม่คิดว่าการนำเข้า / ส่งออกให้การสนับสนุนวิธีการเรียนแบบส่วนตัว แต่อย่างใด ฉันหมายความว่ามันรองรับฟังก์ชั่นที่คล้ายกันในระดับชั้นเรียน แต่ไม่ได้เสนอวิธีการซ่อนอยู่ (เช่นวิธีที่มีอยู่ทั้งหมดเป็นสาธารณะเสมอ)
bvdb

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