การแสดงออกแลมบ์ดาของ C # ก็มีการปิดเช่นกันแต่ไม่ค่อยมีการพูดคุยกันโดยชุมชนหรือหนังสือ C # ฉันเห็นคน JavaScript และหนังสือพูดถึงการปิดตัวมันมากกว่าที่พวกเขาทำในโลก C # ทำไมถึงเป็นอย่างนั้น?
การแสดงออกแลมบ์ดาของ C # ก็มีการปิดเช่นกันแต่ไม่ค่อยมีการพูดคุยกันโดยชุมชนหรือหนังสือ C # ฉันเห็นคน JavaScript และหนังสือพูดถึงการปิดตัวมันมากกว่าที่พวกเขาทำในโลก C # ทำไมถึงเป็นอย่างนั้น?
คำตอบ:
เพราะจาวาสคริปต์ไม่มีคุณสมบัติอย่างเนมสเปซและคุณสามารถเลอะเทอะได้อย่างง่ายดายด้วยการจัดเรียงวัตถุทั่วโลก
ดังนั้นจึงเป็นสิ่งสำคัญที่จะสามารถแยกรหัสบางอย่างในสภาพแวดล้อมการดำเนินการของตัวเอง การปิดนั้นสมบูรณ์แบบสำหรับสิ่งนั้น
การใช้งานการปิดนี้ไม่สมเหตุสมผลในภาษาเช่น C # ที่คุณมีเนมสเปซ, คลาสและอื่น ๆ เพื่อแยกรหัสและไม่ใส่ทุกอย่างในขอบเขตส่วนกลาง
หลักปฏิบัติทั่วไปสำหรับรหัสจาวาสคริปต์คือเขียนแบบนี้:
(function(){
// Some code
})();
อย่างที่คุณเห็นนี่คือการประกาศฟังก์ชันที่ไม่ระบุชื่อตามด้วยการดำเนินการทันที ดังนั้นทุกอย่างที่กำหนดไว้ในฟังก์ชั่นจึงเป็นไปไม่ได้ที่จะเข้าถึงจากภายนอกและคุณจะไม่ทำให้ขอบเขตทั่วโลกสับสน บริบทการดำเนินการของฟังก์ชั่นนี้จะยังคงอยู่ตราบเท่าที่บางโค้ดใช้เช่นฟังก์ชันซ้อนกันที่กำหนดไว้ในบริบทนี้ที่คุณสามารถส่งผ่านเป็นโทรกลับหรืออะไรก็ตาม
Javascript เป็นภาษาที่แตกต่างจาก C # มาก มันไม่ใช่แบบเชิงวัตถุมันเป็นแบบต้นแบบ สิ่งนี้นำไปสู่การปฏิบัติที่แตกต่างกันมากในตอนท้าย
อย่างไรก็ตามการปิดเป็นสิ่งที่ดีดังนั้นใช้งานได้แม้ใน C #!
แก้ไข: หลังจากหารือเกี่ยวกับการแชทของ stackoverflow ฉันคิดว่า anwer นี้ต้องได้รับการพิจารณา
ฟังก์ชั่นในรหัสตัวอย่างไม่ได้เป็นการปิด อย่างไรก็ตาม fucntion นี้สามารถกำหนดตัวแปรท้องถิ่นและฟังก์ชั่นที่ซ้อนกัน ฟังก์ชันที่ซ้อนกันทั้งหมดที่ใช้ตัวแปรโลคัลเหล่านี้เป็นการปิด
นี่เป็นประโยชน์อย่างยิ่งในการแบ่งปันข้อมูลบางอย่างผ่านชุดฟังก์ชั่นโดยไม่ทำให้ขอบเขตทั่วโลกยุ่งเหยิง นี่คือการปิดการใช้งานทั่วไปในจาวาสคริปต์
การปิดเป็นวิธีที่มีประสิทธิภาพมากกว่าการแบ่งปันข้อมูลบางอย่างเช่นนี้ แต่ขอให้เหมือนจริงโดยที่โปรแกรมเมอร์ส่วนใหญ่ไม่รู้เกี่ยวกับการเขียนโปรแกรมเชิงฟังก์ชัน ใน C # คุณจะต้องใช้คลาสหรือเนมสเปซสำหรับการใช้งานประเภทนี้ แต่ JS ไม่ได้จัดให้มี functionnality นี้
คุณสามารถปิดการทำงานได้มากกว่าการปกป้องขอบเขตทั่วโลก แต่นี่คือสิ่งที่คุณจะเห็นในซอร์สโค้ด JS
อาจเป็นเพราะการใช้งานการวางแนววัตถุที่เป็นที่นิยมของ JavaScript ขึ้นอยู่กับการปิด ลองดูตัวอย่างง่ายๆ:
function counter() {
var value = 0;
this.getValue = function() { return value; }
this.increase = function() { value++; }
}
var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());
วิธีการgetValue
และอยู่ในการปิดความเป็นจริงห่อหุ้มเซลล์แสงอาทิตย์ตัวแปรincrease
value
เพราะห้องสมุดหลายแห่งที่ทำให้จาวาสคริปต์ใช้งานได้
ลองดูที่JQuery , PrototypeหรือMooToolsเพียงเพื่อชื่อสามยอดนิยม แต่ละไลบรารีเหล่านั้นจัดเตรียมeach
วิธีสำหรับการรวบรวมเป็นวิธีการทำซ้ำที่ต้องการซึ่งใช้ฟังก์ชันตัววนซ้ำ ฟังก์ชั่นนั้นเมื่อเข้าถึงค่าในขอบเขตด้านนอกจะเป็นการปิด:
[1,2,3].each(function(item) {
console.log(item);
});
และมันก็ไม่ได้หยุดอยู่แค่นั้น: การเรียกกลับใน Ajax การจัดการเหตุการณ์ใน Ext.js และอื่น ๆ ล้วน แต่มีฟังก์ชั่นและถ้าคุณไม่ต้องการที่จะขยายโค้ดของคุณด้วยฟังก์ชั่น 100 ส่วนที่เรียกว่าหนึ่งครั้ง
console.log
ถูกกำหนดในขอบเขตด้านนอกดังนั้นจึงconsole
เป็น 'ตัวแปรอิสระ' และทำไมเป็นผลให้ for-loop ซึ่งไม่มีอะไรแตกต่างออกไป
ฉันเห็นด้วยกับคำตอบอื่น ๆ ที่การเข้ารหัส "ดี" กับ JavaScript นั้นขึ้นอยู่กับการปิด อย่างไรก็ตามนอกเหนือจากนั้นอาจเป็นเพียงคำถามว่าคุณลักษณะแต่ละรายการมีความยาวเท่าใดในแต่ละภาษา JavaScript นั้นมีการปิดโดยทั่วไปนับตั้งแต่มีการใช้งานครั้งแรก ในทางตรงกันข้าม C # มีเพียงพวกเขาตั้งแต่ 3.0 ซึ่งเผยแพร่กับ Visual Studio 2008
โปรแกรมเมอร์ C # ที่ฉันพบจำนวนมากยังคงทำงานในโครงการ 2.0 และแม้ว่าพวกเขาจะทำงานใน 3.0 หรือ 4.0 พวกเขามักจะยังคงใช้สำนวน 2.0 ฉันรักการปิด หวังว่าพวกเขาจะใช้กันอย่างแพร่หลายใน C # เนื่องจากแนวคิดเผยแพร่ในหมู่นักพัฒนา C #
สาเหตุหลักคือเนื่องจาก C # ถูกพิมพ์แบบคงที่และฟังก์ชั่นสามารถเข้าถึงสภาพแวดล้อมที่กำหนดไว้ล่วงหน้าเพียงครั้งเดียวซึ่งขัดขวางการใช้ประโยชน์จากการปิด
ใน JavaScript ในทางกลับกันการปิดใช้งานฟังก์ชั่นจะทำหน้าที่เป็นวิธีการเมื่อเข้าถึงเป็นคุณสมบัติของวัตถุและเป็นวัตถุชั้นหนึ่งพวกเขายังสามารถฉีดเข้าไปในสภาพแวดล้อมที่แตกต่างกันซึ่งช่วยให้รูทีนย่อยทำงานในบริบทที่แตกต่างกัน
เหตุผลหนึ่งที่ฉันต้องเรียนรู้เกี่ยวกับพวกเขาก็เพราะว่าเมื่อคุณวนลูปผ่านองค์ประกอบ DOM (หรืออะไรก็ตามจริงๆ) คุณต้องการที่จะสามารถ "ปิด" หรือ "ห่อหุ้ม" ขอบเขตตัวแปร ดังในตัวอย่างที่โพสต์ที่นี่: /programming/5606059/how-to-create-closure-in-loop-and-store-it-in-variable-for-later-execution