JavaScript Closure
posted on 25 Mar 2009 00:37 by ipats
[เรื่องเขียนโปรแกรม มึนๆ น้อ]
พอดีวันนี้ลองเขียนเล่น แล้วติดปัญหาอยู่อย่างนึง.. ทำเอามึนไปนานโข พอแก้ได้แล้วเลยลองหาข้อมูลดู ปรากฏว่า เค้าก็เป็นกัน 555 (ดีใจ ที่ไม่ได้มึนไปคนเดียว)
ปัญหาที่ว่าเป็นอย่างไร ของดูโค้ดสั้นๆ ข้างล่างนี้เลย (เป็น JavaScript เน้อ)
คำถามคือ.. โค้ดนี้มันจะ alert ค่าอะไรออกมา?
ตอบอย่างรวดเร็ว 5 แน่ๆ
ผิด! ผ่างๆๆๆๆๆ
เหตุผลเพราะ function ที่สร้างขึ้นมาข้างในมันอ้าง i เป็นตัวเดียวกับใน loop ซึ่งมันอ้างแบบอิงตัวแปรเลย ไม่ได้เอาค่ามาใช้อย่างที่ผมคาดว่ามันจะทำ Y-Y
แต่มันไม่ใช่ที่ผมต้องการหน่ะซิ ง่ะ.. เลยต้องหาวิธีแก้ ก็ออกมาเป็นประมาณนี้ (กว่าจะได้.. รากเลือด)
ที่ทำแบบนี้ได้ เพราะเมื่อเรา call makefunc(i) มันจะ pass ค่า i ไปเข้าใน function ซึ่งในนั้นก็จะเป็นอีกสโคปนึง (ประมาณว่ามันจะก็อปค่าไป ไม่ได้อิงกับตัวเดิม)
ทำเสร็จก็ไปค้นๆ ดู เค้ามีอธิบายไว้ค่อนข้างละเอียด (เคสเดียวกันเลย เหอๆ)
Explaining JavaScript scope and closures (อันนี้เค้าใช้ self-invoking functions ไฮโซมาก)
More closure examples
ปล. รากเลือดนะ ไม่ใช่ลากเลือด "ราก" แปลว่าอ้วก (รู้จักครั้งแรกเมื่ออ่านขายหัวเราะ - ใครว่าอ่านการ์ตูนไร้สาระ :p ) เพราะฉะนั้น รากเลือดก็คือ อาการที่เหนื่อยสาหัสจนอ้วกเป็นเลือกนั้นเอง โฮะๆๆ
พอดีวันนี้ลองเขียนเล่น แล้วติดปัญหาอยู่อย่างนึง.. ทำเอามึนไปนานโข พอแก้ได้แล้วเลยลองหาข้อมูลดู ปรากฏว่า เค้าก็เป็นกัน 555 (ดีใจ ที่ไม่ได้มึนไปคนเดียว)
ปัญหาที่ว่าเป็นอย่างไร ของดูโค้ดสั้นๆ ข้างล่างนี้เลย (เป็น JavaScript เน้อ)
var func = [];
for(var i=0; i<10; i++) {
func[i] = function () {
alert(i);
};
}
func[5]();
for(var i=0; i<10; i++) {
func[i] = function () {
alert(i);
};
}
func[5]();
คำถามคือ.. โค้ดนี้มันจะ alert ค่าอะไรออกมา?
ตอบอย่างรวดเร็ว 5 แน่ๆ
ผิด! ผ่างๆๆๆๆๆ
เหตุผลเพราะ function ที่สร้างขึ้นมาข้างในมันอ้าง i เป็นตัวเดียวกับใน loop ซึ่งมันอ้างแบบอิงตัวแปรเลย ไม่ได้เอาค่ามาใช้อย่างที่ผมคาดว่ามันจะทำ Y-Y
แต่มันไม่ใช่ที่ผมต้องการหน่ะซิ ง่ะ.. เลยต้องหาวิธีแก้ ก็ออกมาเป็นประมาณนี้ (กว่าจะได้.. รากเลือด)
function makefunc(i) {
return function () {
alert(i);
};
}
var func = [];
for(var i=0; i<10; i++) {
func[i] = makefunc(i);
}
func[5]();
return function () {
alert(i);
};
}
var func = [];
for(var i=0; i<10; i++) {
func[i] = makefunc(i);
}
func[5]();
ที่ทำแบบนี้ได้ เพราะเมื่อเรา call makefunc(i) มันจะ pass ค่า i ไปเข้าใน function ซึ่งในนั้นก็จะเป็นอีกสโคปนึง (ประมาณว่ามันจะก็อปค่าไป ไม่ได้อิงกับตัวเดิม)
ทำเสร็จก็ไปค้นๆ ดู เค้ามีอธิบายไว้ค่อนข้างละเอียด (เคสเดียวกันเลย เหอๆ)
Explaining JavaScript scope and closures (อันนี้เค้าใช้ self-invoking functions ไฮโซมาก)
More closure examples
ปล. รากเลือดนะ ไม่ใช่ลากเลือด "ราก" แปลว่าอ้วก (รู้จักครั้งแรกเมื่ออ่านขายหัวเราะ - ใครว่าอ่านการ์ตูนไร้สาระ :p ) เพราะฉะนั้น รากเลือดก็คือ อาการที่เหนื่อยสาหัสจนอ้วกเป็นเลือกนั้นเอง โฮะๆๆ
Tags: closure, javascript, programming8 Comments
ไอ้แพท..





มาสเตอร์แชมป์
จาวา... เอ๋อเลย *-*
#1 By Aelita~[-X-]~ on 2009-03-25 00:50