JSEXP or: How I Learned to Coding and Love the JavaScript

*(ชื่อบทความมาจาก [Dr. Strangelove](https://en.wikipedia.org/wiki/Dr._Strangelove)*

@[winwanwon](https://twitter.com/winwanwon) จะเรียน JavaScript เราเลยว่าประสบการณ์เรียน JavaScript เรามันแปลกกว่าการเรียนภาษาอื่นๆ เลยมาเขียนไว้หน่อย

ตอนป. 6 มีอยู่ project ตัวนึง (source ผมหายไปจากการฟอร์แมตโง่ๆ ครั้งนั้น แล้วก็เพื่อนไม่ได้เก็บไว้) ซึ่งผมพูดถึงบ่อยแล้ว มันคือ DarkWorld ซึ่งเป็น megaproject ตัวแรกของผม มันเกิดจากว่าผมเห็นเพื่อนในห้องมันเอาหนังสือแฮกกิ้งมาอ่านเลยเข้าไปคุยด้วย หลังจากนั้นไปเดือนนึงเราก็ชวนกันทำ project และผมก็เลือก project เกม ซึ่งเกมเนี่ยผมพยายามเขียนมาแต่ขี้เกียจมาตั้งแต่ป. 4-5 แล้วมั้ง (มีอันนึงเคยทำเกมจุดขายคือหน้า login สวยใน IE เพราะมันใช้ HTTP Authorization ซึ่งใน IE จะเหมือน login network drive)

ทีนี้ทำเกมมันก็ต้องมีจุดขาย ผมให้เพื่อนในห้องเล่นได้ง่ายๆ แค่ชวนว่าเอออันนี้พวกเราในห้องทำกันก็ได้กลุ่ม user มาเป็นสิบแล้ว (คาบคอมผมเห็นหลายคนเล่น เป็นอะไรที่ดีใจมาก) แต่จุดขายที่ผมเลือกคือ “เกมแรกของไทยที่ใช้ AJAX” ซึ่งสมัยนั้น AJAX มันเป็นอะไรที่เท่มากและเพิ่งมี เกมออนไลน์บนเว็บไทยก็พอมีอยู่บ้าง เจ้าใหญ่สุดคือ oceanica (เข้าไปล่าสุดเมื่อหลายปีก่อนมันยังคล้ายๆ สมัยก่อนโน้นอยู่เลย) ก็มีแต่ ajax chat ตัวเกมคลิกแล้วก็รอโหลดอยู่ดี

(ที่จริงไอ้คำโฆษณาแบบนี้ผมว่ามันขาย user ได้จริงหรอฟะ แต่ตอนนั้นเป็นเด็กน้อยก็คิดได้แค่ว่ามันเท่อะนะ แล้วไอ้คุณเพื่อนในกลุ่มก็รู้จักคำนี้ดีก็เลยเห็นดีเห็นงามไปด้วยไม่ได้คัดค้านอะไร – -!)

ฟีเจอร์แรกสุดในเกมที่ควรรีบมีและเป็น AJAX คือ Chat ผมเลยหาข้อมูลว่าจะเขียนยังไงดีด้วย PHP และผมไม่รู้เรื่อง JavaScript บังเอิญไปเจอ [xajax](http://xajaxproject.org/) ซึ่งมันเป็นอะไรที่เจ๋งมากเพราะสามารถแก้ไข DOM ฝั่ง client ได้โดยไม่ต้องรู้ JS สักนิด

ทีนี้ต่อมาผมก็บอกไปแล้วว่า ajax chat มันไม่ใช่ฟีเจอร์เกม ฉะนั้นเกมต้องมี ajax ต่อมาเลยมีฟีเจอร์ ajax แรก มันคือร้านขายของ แต่เกมนี้ผมคิดร้านขายของไปได้ไงไม่รู้ ให้เอาเงินไปซื้อ exp ในแต่ละสกิลได้ – – !! (เข้าใจว่าลอกเลียนแบบมาจากอีกเกมของสนพ. ไทยชื่อดังซึ่งโดนผมยิงจนปิดไปแล้ว ยิงในที่นี้ไม่ใช่ยิงให้ล่ม แต่ยิงเข้าไปหน้าตีมอนรัวๆๆๆ จนไอดีผมขึ้นที่ 1 ในเกมแล้วเหมือนจะโดนลบ เลยครีใหม่แล้วทำอีก อิอิ) เวลากดซื้อปุ๊บมันก็จะยิง xajax เข้าไปที่ server ให้เซฟแล้วก็ส่งกลับมา

มาถึง beta 3 ผมบอกว่าเวอร์ชั่นนี้เกมจะเริ่มเป็นเกมจริงๆ ใน beta 4 ซึ่งผมเขียนรุ่นนี้อยู่สามวัน (beta 2 2 วัน) โดยใช้ code DHTML หมดเลยจาก dynamic drive เรียกได้ว่าเกมหน้าเดียวมีทุกเมนู กดไปก็เป็น iframe แต่จะมี AJAX Polling ไปเรื่อยๆ ที่ server สำหรับ notify เวลามีคน PK เพราะuser บ่นมาว่าโดน PK ไม่เห็นมีอะไรเตือน

สุดท้ายจบ project นี้ไปด้วยว่าทีมงานทะเลาะกันแยกกัน…อ้าว แล้วไหนว่าเรียน JavaScript

ทีนี้มาตอนม. 1 มันมี script.acuolo.us ออกมา เป็น animation library ทำวู๊บๆ ได้ ผมละแบบว่าเหยดเข้พระเจ้าจอร์ช xajax มันไม่มีแบบนี้ ก็เลยลองโหลดมาดู *โดยที่ไม่ได้ลง prototype* แน่นอนว่าใช้ไม่ได้เพราะไม่มี prototype แต่เด็กม. 1 ไม่รู้เรื่อง ก็เลยไปหาตัวอื่นหลายตัว รวมถึง… [เขียน animation library เอง!](http://whs.whs.in.th/archive/whsjs.html) (setTimeout + height++ เอา) เพราะตัวไหนก็อ่านไม่รู้เรื่อง ส่วนไอ้พวกคำสั่ง setTimeout document.getElementById นี่ก็คือไป view source ชาวบ้านเขา เห็นเค้าใช้กันก็เลยเออเอามั่ง `function $(i){return document.getElementById(i);}` นี่จำขึ้นใจ (สมัยนี้ใช้ jQuery หมดแล้วแหละ จะไปเรียนแบบผมไม่ได้แล้ว)

*(ส่วน project สุดท้ายที่ใช้ xajax คิดว่าเป็น [ตัวนี้](http://whs.whs.in.th/archive/songkran/) ที่ยังหาเจอ ก๊อปโค้ดมาจาก exteen เติม ajax+save)*

จนมาเจอตัวนึง คือ moo.fx ของ prototype นี่แหละ ดูไปดูมาไปเจอ MooTools เจ้าของเดียวกัน เป็นแบบครบจบในตัว ผมเลยเอามาลอง แล้วก็ใช้ไอ้นี่ทำมาหลายงาน ไม่ว่าจะเป็น [Clickr](http://whs-clickr.appspot.com/clickr.html) (ม. 2) [แข่งคอมภายนอกโรงเรียน](http://whs.whs.in.th/archive/htm32/) (กรรมการชมว่า accordion สวยเนอะ) [Ubuntuclub Headline](http://whs.whs.in.th/archive/headline/) (โหลดช้าหน่อย อันนี้ทำไว้ว่าจะเป็น homepage ตัวเอง สุดท้ายไม่ได้ใช้หรอก) [Get Ubuntu](http://whs.whs.in.th/archive/ubuntu/) (ถ้าจำไม่ผิดหน้านี้น่าจะได้ใช้)

แต่งานเลี้ยงมีวันเลิกรา MooTools 1.2 เปลี่ยน API คำสั่ง Animation ไม่ใช่ Fx.Styles แล้ว ผมก็เลยว่าไม่ใช้มันแล้ว บังเอิญตอนนั้นเจอ jQuery ด้วย เลยเห็นหน้าแรกแล้วแบบว่าเฮ้ยเจ๋ง MooTools ต้องมานั่ง new Fx.Styles ไรเยอะแยะ นี่ $(“..”).animate แถม MooTools มันทำได้ทีละอันใน $() นี่ $ พี่ท่านเล่นใส่ CSS Selector เข้าไปได้เลย (ใน MooTools มี ผมก็เคยต้องใช้ มันใช้คำสั่ง $$ คืนเป็น Array ให้ไปลูปเอาเอง แต่ jQuery จะ match ล้านอันท่านก็สั่งเหมือนอันเดียว ลูปมันจัดการให้) ก็เลยว่าเออ เอาวะ ลอง

ผมจำไม่ได้ว่า jQuery ตัวแรกที่เขียนคืออะไร แต่ผมจำได้ตอนเลือก​ MooTools ตอนนั้น jQuery ผมก็เห็น แต่ผมเห็นตัวอย่างอันเดียวกันนี่แหละที่มันเทพๆ แล้วผมบอกว่ามันเทพไปว่ะ ล้ำลึกจนงง

สิ่งที่พบจาก jQuery คือมันทำงานเกี่ยวกับ DOM ได้สะดวกรวดเร็วมาก แต่นอก DOM แล้วจะทำอะไรไม่สะดวก เพราะ MooTools มัน extend native object ไปเลย (พูดง่ายๆ ว่า [‘1′,’2′,’3’].unique() อะไรแบบนี้ได้เลย jQuery ไม่มีแม้แต่คำสั่ง unique) อันนี้ไม่ใช่ปัญหา ผมหา library มาใส่ได้ ซึ่งตัวนึงที่ใช้บ่อยช่วงนั้นคือ [phpjs](http://phpjs.org/) อันนี้ตัดเฉพาะคำสั่งที่ใช้ไปได้ ไม่ต้องเอาไปหมด

ต่อมา project นึงที่ทำให้ผมรู้เรื่อง JavaScript เยอะมากคือ Twitica Desktop นี่แหละ ตอนนั้นผมเขียน JS เป็นอยู่แล้วแต่ทำไอ้นี่มันเป็น project ใหญ่ที่จะได้เรียนอะไรเยอะ และยิ่งเป็นแบบไม่มีเซิร์ฟเวอร์ด้วย เขียนอะไรไม่เป็นหาทางหลบไม่ได้ต้องชนกับปัญหาตรงๆ (ถึงตอนนี้ผมว่าโค้ด Twitica บางจุดมันเกินอ่านได้แล้วอะ โดยเฉพาะตรงวาดทวิตนี่แบบว่า engineering mistake)

ถัดมาอีกอันที่ผมรู้สึกว่าเรียน JS ไปมากขึ้นเยอะ มันคือ Twitica for webOS ถึงมันจะไม่ออกแต่มันเสร็จ ผมเขียนสองวันเสร็จได้ด้วยพลังอะไรไม่รู้ แต่กลับไปอ่านพบว่าบางอย่างเขียนไปด้วยวิธีที่ผิดแต่ผลลัพท์ถูก ข้างตัวมีตำรา webOS หนาเท่าหนังสือสรุปฟิสิกส์ ที่เรียนได้เพราะ webOS ใช้ Prototype และนั่นแปลว่าคุณต้องใช้ Prototype ไม่ใช่ jQuery (ถึงจะใช้พร้อมกันได้ในทางปฎิบัติ แต่เราว่ามันไม่ควรทำบนมือถือนะ) ทำให้เราเจอกับคอนเซปต์แปลกๆ เช่น bound function ซึ่งพบว่าบั๊กบางตัวใน Twitica ที่เราหาคำตอบไม่ได้ก็ต้องแก้ด้วย bound function นี่แหละ

*(bound function คือ function ที่เวลาเรียกแล้วจะมี argument, this คงที่ เช่น (ถ้าใช้ prototype.js) `var x = “5”; var y = (function(x){alert(x);}).bind(null, x); x=”30″;` เวลาเราเรียก y() จะพบว่าขึ้นว่า 5 เพราะค่าของ x = “5” ตั้งแต่ตอน bind function นั้นแล้ว (สังเกตว่าเรียก y() เฉยๆ ไม่มีการระบุ argument เพราะ argument x มาจากการ bind) แต่ถ้าไม่มีการ bind แล้วเรา y() จะขึ้นว่า 30 ส่วน null ข้างหน้าใน bind มันเป็นการกำหนดค่าของ this ใน function y ถ้าไม่ได้สนใจก็ใส่อะไรมั่วๆ ไปเหอ)*

ตอนนี้ผมเขียน menome และตอนผมเขียน menome forum ได้ลอง underscore + backbone และพบว่ามันคืออะไรที่เจ๋งมาก underscore คือ prototype นั่นแหละ แต่ว่าไม่ผูกกะ native function ซึ่งส่วนตัวผมอยากให้ผูกมากกว่าเพราะเขียนสะดวกกว่า แต่ว่ามันออกแบบมาไม่ให้ชนกับ jQuery หรืออื่นๆ เลยทำให้ต้องใช้ตัวนี้แทนที่จะใช้ prototype เวลา bind ก็เช่น `_.bind(function(){}, null, x)`

ส่วน backbone เป็นอะไรที่อยากแนะนำนะถ้าบรรลุ JS พื้นฐานไปแล้ว อธิบายง่ายๆ คือเหมือนมี Object เก็บข้อมูลอยู่ พอ object นี้มีการเปลี่ยนแปลงจะส่งสัญญาณออกมา แล้วเราจะเขียน view อีกตัวไปต่อสัญญาณพวกนี้ อาจจะให้ทำการ render html ใหม่ หรือทำอะไรก็แล้วแต่ และสุดท้ายสามารถ sync ข้อมูลขึ้นลงกับฝั่ง server ได้อีกด้วย

จบห้วนๆ อีกแล้ว ไม่รู้ทำไมชอบเขียนอะไรจบแบบนี้