ความหมายของฟังก์ชัน
คำว่า
ฟังก์ชัน (function) นั้นเป็นคำที่มีความหมายหลากหลาย
ซึ่งแล้วแต่ว่าพูดถึงเรื่องอะไรอยู่
อย่างสำหรับในทางคณิตศาสตร์แล้วฟังก์ชันคือสิ่งที่แสดงความสัมพันธ์ระหว่างค่าจำนวนหรือปริมาณบางอย่าง
โดยมักจะอยู่ในรูปของกล่องใบหนึ่งที่ใส่ค่าอะไรบางอย่างเข้าไปแล้วก็จะให้อะไรบางอย่างคืนกลับออกมา
เช่น
f(x) = (x+8)/2
แบบนี้เมื่อใส่ค่า x เป็น 2 ก็จะได้ค่า f(x) เป็น 5 กลับมา
ฟังก์ชันในภาษาโปรแกรมต่างๆก็เป็นสิ่งที่มีแนวคิดใกล้เคียงกันนี้
คือจะมีการป้อนค่าลงไป แล้วเกิดการคำนวณหรือทำอะไรบางอย่างในฟังก์ชันนั้น
แล้วคืนค่าบางอย่างกลับออกมา
ยกตัวอย่างเช่น ฟังก์ชัน parseInt ในจาวาสคริปต์
var s = "005.00";
var x = parseInt(s); // x จะกลายเป็น 5
parseInt ในที่นี้เมื่อใส่ค่า "005.00"
เข้าไปจะถูกตีความเป็นตัวเลขจำนวนเต็ม 5 แบบนี้เรียกว่าฟังก์ชันนี้คือค่า 5 ออกมา
ค่าที่คืนออกมาอาจนำมาใช้ทันที หรืออาจจะถูกเก็บไว้ในตัวแปรก็ได้
แบบนี้เรียกว่า
การคืนค่า (return) ของฟังก์ชัน
เพียงแต่ว่าฟังก์ชันในโปรแกรมนั้นอาจไม่จำเป็นต้องคืนค่ากลับมาเสมอไป
แต่แค่เอาค่าที่ใส่ไปไปทำอะไรบางอย่าง
ดังเช่นฟังก์ชัน alert ซึ่งแนะนำไปตั้งแต่ต้น
ฟังก์ชันนี้แค่นำค่าที่ป้อนเข้าไปไปแสดงผลออกมาเท่านั้น ไม่ได้มีการคืนค่ากลับมา
หมายความว่าต่อให้เอาตัวแปรมารับค่า ก็จะได้ค่าว่างเปล่า คือเป็น undefine
เช่น
var al = alert("555+");
แบบนี้จะมีข้อความ 555+ เด้งออกมา แต่ค่าของตัวแปร al จะกลายเป็น undefined
โดยรายละเอียดแล้ว ฟังก์ชันในโปรแกรมแต่ละภาษาจะต่างกันออกไป
สำหรับในจาวาสคริปต์นั้น ใน
บทที่ ๓
ได้แนะนำไปแล้วว่า สำหรับในจาวาสคริปต์แล้วฟังก์ชันก็เป็นชนิดข้อมูลขนิดหนึ่ง
และในจาวาสคริปต์มีการสร้างฟังก์ชันที่ง่ายดายและยืดหยุ่นมาก
ฟังก์ชันคือสิ่งที่จะทำงานก็ต่อเมื่อใส่วงเล็บไว้ข้างหลัง
แล้วใส่ค่าที่ต้องการป้อนเข้าไปทำงานในวงเล็บนั้น ค่าที่ใส่ไปนั้นเรียกว่า
"อาร์กิวเมนต์" (argument)
เช่นใน
alert("555+")
นี้ "555+"
คืออาร์กิวเมนต์ของฟังก์ชัน alert นี้
ฟังก์ชันไหนจะต้องการอาร์กิวเมนต์อะไรบ้างนั้นถูกกำหนดไว้ตั้งแต่ตอนสร้างฟังก์ชันแล้ว
เมื่อเข้าใจหลักการและความหมายของฟังก์ชันในเบื้องต้นแล้ว
ต่อไปจะมาแนะนำวิธีการสร้างฟังก์ชัน ซึ่งมีอยู่หลายวิธีด้วยกัน
การสร้างฟังก์ชันไร้ชื่อด้วยคำสั่ง function
วิธีการสร้างฟังก์ชันที่ง่ายและพบบ่อยที่สุดคือการใช้คำสั่ง function
ในการสร้าง
การสร้างแบบนี้เป็นการสั้งฟังก์ชันไร้ชื่อ
ความหมายของคำว่าไร้ชื่อนี้จะอธิบายในตอนหลัง
ตอนที่เขียนถึงการสร้างฟังก์ชันอีกแบบ คือแบบมีชื่อ
โครงสร้างเป็นดังนี้
var ชื่อตัวแปร = function(พารามิเตอร์){
เนื้อหาในฟังก์ชัน
}
"พารามิเตอร์" (parameter)
ก็คือค่าที่ต้องการรับเข้ามาใช้ในฟังก์ชัน
เวลาเรียกใช้ฟังก์ชันที่จริงอาร์กิวเมนต์กับพารามิเตอร์นั้นความหมายใกล้เคียงกันมาก
อาจจำง่ายๆว่าตอนที่สร้างฟังก์ชันขึ้นจะเรียกว่าพารามิเตอร์
แต่ตอนที่เรียกใช้ฟังก์ชันจะเรียกว่าอาร์กิวเมนต์
คือตอนเรียกใช้ฟังก์ชัน ค่าที่ป้อนให้ฟังก์ชันจะเรียกว่าอาร์กิวเมนต์
และอาร์กิวเมนต์นั้นจะไปถูกแทนลงในพารามิเตอร์ของฟังก์ชัน
ตัวอย่างการสร้าง ลองสร้างฟังก์ชันง่ายๆที่แค่มีการใช้ alert เพื่อแสดงค่า
(x+8)/2
var f = function(x) {
alert((x + 8) / 2);
};
จากนั้นก็เรียกใช้งานโดยใส่ชื่อฟังก์ชันแล้วตามด้วยวงเล็บ ในวงเล็บป้อนค่าลงไป
f(2); // ได้ 5
f(3); // ได้ 5.5
ในที่นี้เมื่อ 2 เป็นอาร์กิวเมนต์ จะถูกแทนค่าลงในพารามิเตอร์ x แล้วจะขึ้น alert
เลข 5 ออกมา ถ้าใส่ 3 ไปก็จะกลายเป็น 5.5
ตัวอย่างข้างต้นนี้เป็นกรณีของฟังก์ชันที่ไม่มีการคืนค่า
แต่สำหรับฟังก์ชันที่มีการคืนค่าจะต้องมีคำสั่ง return
var f = function(x) {
return (x + 8) / 2;
};
var a = f(2);
alert(a); // ได้ 5
ฟังก์ชันที่มีพารามิเตอร์หลายตัว
พารามิเตอร์อาจมีกี่ตัวก็ได้ เวลาเรียกใช้ก็ต้องใส่อาร์กิวเมนต์ตามจำนวนนั้น
ค่าที่ใส่จะถูกแทนลงในพารามิเตอร์ตามลำดับ
var f = function(x, y, z) {
return "x=" + x + " y=" + y + " z=" + z;
};
alert(f(2, 3, 4)); // ได้ x=2 y=3 z=4
ถ้าจำนวนของอาร์กิวเมนต์น้อยกว่าพารามิเตอร์ ตัวที่เกินมาจะเป็น undefined
alert(f(2, 3)); // ได้ x=2 y=3 z=undefined
ถ้าใส่เกินมา ตัวที่เกินจะถูกมองข้ามไป ไม่ได้ใช้
ผลก็จะไม่ต่างจากใส่พอดีจำนวน
alert(f(2, 3, 4, 5)); // ได้ x=2 y=3 z=4
แต่ก็ไม่ใช่ว่าการใส่พารามิเตอร์เกินมาจะไม่มีผลใดๆเลย
ที่จริงในฟังก์ชันจะมีตัวแปรติดตัวที่เรียกว่า arguments อยู่
ซึ่งจะเก็บอาร์กิวเมนต์ทั้งหมดที่ถูกใส่เข้ามา เช่น
var f = function(x) {
return "x=" + x + " arguments=" + arguments;
};
alert(f(3, 5)); // ได้ x=3 arguments=[object Arguments]
arguments นี้เป็นออบเจ็กต์ตัวหนึ่ง
ซึ่งเก็บอาร์กิวเมนต์แต่ละตัวที่ใส่เข้าไปไว้
var f = function(x) {
var s = "x=" + x;
s += " arg0=" + arguments[0];
s += " arg1=" + arguments[1];
s += " arg2=" + arguments[2];
return s;
};
alert(f(3, 5)); // ได้ x=3 arg0=3 arg1=5 arg2=undefined
ด้วยการใช้ arguments จะทำให้สามารถสร้างฟังก์ชันที่ไม่จำกัดตัวแปรได้
อย่างไรก็ตาม สำหรับใน ES6 มีวิธีที่ดีกว่าการใช้ arguments นั่นคือการใช้ ...
(จุดสามจุด) ทำให้ความจำเป็นที่จะต้องใช้ arguments นั้นลดลงไป
แต่จะยังไม่เขียนถึงตรงนี้ จะไปอธิบายในเนื้อหาในส่วนของ ES6
เกี่ยวกับคำสั่ง return
คำสั่ง return มีรายละเอียดปลีกย่อยในการใช้ที่จำเป็นต้องมาเน้นกันสักหน่อย
อย่างแรกคือ จริงๆแล้วคำสั่ง return ไม่ได้จำเป็นต้องอยู่ท้ายสุดเสมอไป แต่ถ้าเจอ
return ฟังก์ชันจะสิ้นสุดทันที สิ่งที่อยู่หลัง return จะไม่ได้ถูกทำ
เช่น
var f = function() {
s = "เธอเก่ง";
return s;
s += "น้อยกว่าเขา";
alert(s);
};
alert(f()); // ได้ เธอเก่ง
แบบนี้คำสั่งในฟังก์ชันหลัง return s จะไม่ทำงาน
ต่อมา คำสั่ง return สามารถใส่หลายอันก็ได้
แต่เฉพาะอันที่เจอก่อนเท่านั้นจึงจะถูกใช้
ที่มักเจอบ่อยก็คือเมื่อใช้ if เช่น
var f = function(x, y) {
if (x > y) return "x มากกว่า y";
else if (x == y) return "x เท่ากับ y";
else return "x น้อยกว่า y";
};
alert(f(4, 6)); // ได้ x น้อยกว่า y
alert(f(19, 7)); // ได้ x มากกว่า y
ที่จริงแล้วในตัวอย่างนี้ else อาจละได้ เพราะ ถ้าเข้าเงื่อนไขตั้งแต่แรกก็เจอ
return ตัวแรก ยังไงคำสั่งที่อยู่ใน else ก็ไม่ถูกใช้
ดังนั้นในฟังก์ชันเขียนแบบนี้ก็ได้ผลเหมือนเดิม
var f = function(x, y) {
if (x > y) return "x มากกว่า y";
if (x == y) return "x เท่ากับ y";
return "x น้อยกว่า y";
};
return ไม่จำเป็นต้องมีค่าตามหลัง อาจใส่ return เฉยๆ
กรณีนี้จะหมายความว่าให้สิ้นสุดการทำงานของฟังก์ชันโดยไม่ส่งคืนค่าใดๆออกมา
ค่าคืนกลับของฟังก์ชันนั้นจะกลายเป็น undefined
var f = function(x) {
return;
};
var a = f(29);
alert(a); // ได้ undefined
ค่าคืนกลับต้องเขียนอยู่บรรทัดเดียวกันกับ return
ข้อควรระวังอีกอย่างคือหลัง return
ต้องตามด้วยค่าที่ต้องการให้คืนกลับทันทีโดยห้ามขึ้นบรรทัดใหม่
เพราะถ้าขึ้นบรรทัดใหม่จะถูกตีความเป็นคนละคำสั่งกัน จะกลายเป็นว่าให้ return
โดยไม่มีการคืนค่า
var f = function(x) {
return
x / 2 - (x * x) / 10 + 5;
};
var a = f(29);
alert(a); // ได้ undefined
จริงอยู่ว่าหลายคำสั่งในจาวาสคริปต์สามารถเขียนค่าในบรรทัดใหม่ได้ แต่ return
ไม่เป็นเช่นนั้น ถ้าไม่มีอะไรต่อท้ายทันทีจะถือว่าคืนค่าเปล่าทันที
แต่ก็สามารถใช้วงเล็บช่วยได้ หากต้องการขึ้นบรรทัดใหม่จริงๆ เช่น
var f = function (x) {
return (
(x / 2) - x * x / 10 + 5
);
};
var a = f(20);
alert(a); // ได้ -25
การสร้างฟังก์ชันมีชื่อ ด้วยคำสั่ง function
การสร้างฟังก์ชันที่อธิบายมาตั้งแต่ต้นบทนั้นเป็นการสร้างฟังก์ชันแบบไร้ชื่อ
อีกวิธีในการสร้างฟังก์ชันคือสร้างโดยใช้คำสั่ง function
นำหน้าชื่อตัวแปรฟังก์ชัน คือเขียนแบบนี้
function ชื่อตัวแปร(พารามิเตอร์){
เนื้อหาในฟังก์ชัน
}
ตัวอย่าง
function f(x) {
return "2x = " + x * 2;
}
alert(f(1.1)); // ได้ 2x = 2.2
จะเห็นว่าคล้ายกันมาก แต่แบบนี้ชื่อตัวแปรที่จะแทนฟังก์ชันจะถูกใส่ไว้ด้านหลัง
การเขียนแบบนี้มีข้อแตกต่างจากวิธีแรกตรงที่การสร้างแบบนี้จะเป็นการตั้งชื่อให้ฟังก์ชันไปด้วย
จะเห็นได้จากตอนที่สั่งดูค่า เช่นโดยใช้ alert จะมีชื่อของฟังก์ชันขึ้น
ตรงกับชื่อตัวแปรที่ใช้แทนฟังก์ชัน
function wangplao() {}
alert(wangplao); // ได้ function wangplao() {}
แต่หากลองใช้วิธีสร้างแบบไร้ชื่อ
ฟังก์ชันที่ได้จะไม่มีชื่อฟังก์ชันปรากฏขึ้นมาด้วย
wangplao = function() {};
alert(wangplao); // ได้ function() {}
ดังนั้นในกรณีฟังก์ชันไร้ชื่อ ตัวแปรเป็นแค่ตัวเก็บฟังก์ชัน
ชื่อตัวแปรไม่ได้เป็นชื่อฟังก์ชันไปด้วย ตัวฟังก์ชันจริงๆนั้นไร้ชื่อ
นอกจากนี้ข้อแตกต่างอีกอย่างคือเรื่องลำดับในการทำงานของโปรแกรม
ขอยกตัวอย่างดังนี้
กรณีฟังก์ชันไร้ชื่อ
alert(f); // ได้ undefined
f = 1;
alert(f); // ได้ 1
var f = function(x) {return "2x = " + x * 2;}
alert(f); // ได้ function f(x) {return "2x = " + x * 2;}
f = 1;
alert(f); // ได้ 1
กรณีฟังก์ชันมีชื่อ
alert(f); // ได้ function f(x) {return "2x = " + x * 2;}
f = 1;
alert(f); // ได้ 1
function f(x) {return "2x = " + x * 2;}
alert(f); // ได้ 1
f = 1;
alert(f); // ได้ 1
ความแตกต่างตรงนี้บอกให้เรารู้ว่า การนิยามฟังก์ชันแบบไร้ชื่อ
(เอาชื่อตัวแปรขึ้นต้น) นั้น
ตัวแปรนั้นจะกลายเป็นฟังก์ชันทันทีที่ถึงบรรทัดที่สร้างฟังก์ชันใส่ตัวแปรนั้น
และก่อนที่จะถูกนิยามขึ้น ค่าของตัวแปรนั้นจะเป็น undefined
หรือเป็นเท่ากับค่าที่ถูกใส่ไว้ในตัวแปรตั้งแต่ก่อนนิยามฟังก์ชัน
ซึ่งเป็นไปตามลำดับที่ควรจะเป็นเข้าใจได้ไม่ยาก
ส่วนการนิยามฟังก์ชันแบบมีชื่อ (ใช้ function ขึ้นต้น) นั้น
ไม่ว่าจะวางไว้ส่วนไหนในโปรแกรม ก็จะถูกอ่านก่อนเสมอ
ดังนั้นแม้แต่ส่วนที่วางไว้ก่อนบรรทัดที่นิยามฟังก์ชัน
ก็จะเห็นว่าตัวแปรที่ประกาศเป็นฟังก์ชันนั้นมีสถานะเป็นฟังก์ชันอยู่
แต่ในส่วนที่อยู่หลังจากที่มีการเขียนค่าอย่างอื่นทับตัวแปรนั้นไป
ตัวแปรนั้นจะกลายเป็นค่านั้นไป
แม้ว่าจะอยู่ก่อนหน้าบรรทัดที่ประกาศฟังก์ชันก็ตาม
ดังนั้นเพื่อไม่ให้สับสน กรณีที่ใช้วิธีนี้ควรจะวางไว้ในบรรทัดส่วนขึ้นต้นโปรแกรม
เพราะใส่ตรงไหนก็มีผลเหมือนกัน แบบนี้ถ้าเอาไว้ข้างหลังจะยิ่งทำให้สับสนได้
การสร้างฟังก์ชันด้วย new Function
อีกวิธีที่ใช้สร้างฟังก์ชันขึ้นมาคือใช้คอนสตรักเตอร์ คือเขียน new Function
(คราวนี้ต้องขึ้นต้นด้วยตัว F ตัวพิมพ์ใหญ่)
โครงสร้างเป็นดังนี้
var ชื่อตัวแปร = new Function(พารามิเตอร์, ..., เนื้อหาฟังก์ชัน)
ตัวอย่าง
var haPhuenthiSamliam = new Function("than", "sung", "return than*sung/2;");
alert(haPhuenthiSamliam); // ได้ function anonymous(than,sung) {return than * sung / 2;}
alert(haPhuenthiSamliam(4, 5)); // ได้ 10
เทียบเท่ากับการเขียนฟังก์ชันไร้ชื่อด้วย function แบบนี้
var haPhuenthiSamliam = function(than, sung) {return (than * sung) / 2;};
alert(haPhuenthiSamliam); // ได้ function(than, sung) {return (than * sung) / 2;}
วิธีนี้อาจมีโอกาสใช้น้อยกว่า
เพราะเขียนยากเนื้อหาภายในฟังก์ชันถูกเขียนในรูปแบบของสายอักขระทั้งหมดจึงดูยาก
ผิดพลาดได้ง่าย
ข้อดีของวิธีนี้ก็คือเนื่องจากสามารถสร้างฟังก์ชันขึ้นจากสายอักขระได้
จึงมีความยืดหยุ่นในการใช้งาน
เช่นสามารถใช้เพื่อเขียนโปรแกรมให้ผู้ใช้สามารถเขียนฟังก์ชันใช้งานเองโดยตรง
ขอบเขตการใช้งานของตัวแปร
ปกติแล้วหากมีการประกาศตัวแปรขึ้นภายในโครงสร้างการนิยามฟังก์ชัน
ตัวแปรนั้นจะมีผลแค่ภายในฟังก์ชันนั้น
ดังนั้นหากเรียกตัวแปรนั้นนอกฟังก์ชันก็จะพบว่าไม่มีค่า
แม้ว่าจะมีการเรียกใช้ฟังก์ชันนั้นแล้วก็ตาม เช่น
var f = function(x) {
var k = 5;
alert(k + x);
};
f(6); // ได้ 11
alert(k); // ได้ ReferenceError: k is not defined
เพราะว่ากรณีนี้ k จะถือว่าเป็น
ตัวแปรเฉพาะที่ (local variable)
คือใช้ได้เฉพาะที่ในกรอบวงเล็บปีกกา { } ที่เป็นโครงสร้างฟังก์ชัน
อย่างไรก็ตาม หากประกาศตัวแปรโดยไม่ใช้ var ตัวแปรนั้นจะเป็น
ตัวแปรครอบคลุม (global variable)
นั่นคือตัวแปรที่สามารถเรียกใช้จากที่ไหนก็ได้ในโปรแกรม
var f = function(x) {
k = 5;
alert(k + x);
};
f(6); // ได้ 11
alert(k); // ได้ 5
ปกติแล้วการใช้ตัวแปรแบบครอบคลุมนั้นเป็นสิ่งที่มักจะถูกหลีกเลี่ยง
เพราะทำให้โปรแกรมเข้าใจได้ยากขึ้น มีโอกาสเกิดข้อผิดพลาดได้ง่าย
จากข้อแตกต่างตรงนี้ ทำให้เวลาประกาศตัวแปรมักจะต้องใส่ var ไว้
เพื่อให้รู้ว่าเป็นตัวแปรที่มีผลเฉพาะในขอบเขตนั้น
แต่ตัวแปรที่ประกาศข้างนอก จะใส่ var
หรือไม่ก็ถือเป็นตัวแปรครอบคลุมที่ใช้ได้ทุกที่เหมือนกัน เช่น
var a = 10;
var f = function() {
alert(a);
};
f(); // ได้ 10
แบบนี้ตราบใดที่ไม่มีการประกาศตัวแปร a ภายในฟังก์ชัน f ตัวแปร a ภายในฟังก์ชัน f
ก็จะยังถูกตีความว่าเป็นตัวแปร a จากด้านนอกอยู่
ที่ไม่นิยมใช้ตัวแปรครอบคลุมก็เพราะกรณีที่ตัวแปรในฟังก์ชันเผลอไปซ้ำกับตัวแปรนอกฟังก์ชันจะทำให้เกิดปัญหาที่ไม่คาดคิดได้
ลองดูตัวอย่างต่อไป
var a = 7;
var f = function() {
var a = 2;
alert(a);
};
f(); // ได้ 2
alert(a); // ได้ 5
กรณีนี้ตัวแปร a มีการประกาศไว้ข้างนอก และในฟังก์ชันก็มีการประกาศด้วย
แบบนี้ตัวแปร a ข้างในและนอกถือเป็นคนละตัว
แต่ถ้าหากไม่ใส่ var ด้านใน จะทำให้ตัวแปร a ถูกตีความว่าเป็นตัวเดียวกับ a
ข้างนอก ค่าจึงถูกเขียนทับไป
var a = 7;
var f = function() {
a = 2;
alert(a);
};
f(); // ได้ 2
alert(a); // ได้ 2
แต่ความซับซ้อนของเรื่องนี้ไม่ได้มีอยู่แค่นั้น
เมื่อมีการใช้ var ประกาศตัวแปรเฉพาะที่ในฟังก์ชัน
กรณีที่มีการเรียกใช้ตัวแปรเฉพาะที่ก่อนที่จะมีการประกาศ จะพบว่าค่านั้นเป็น
undefined
var ahan = "ข้าวเกรียบ";
var f = function() {
alert(ahan); // ได้ undefined
var ahan = "ข้าวตัง";
alert(ahan); // ได้ ข้าวตัง
};
f();
alert(ahan); // ได้ ข้าวเกรียบ
นี่แสดงให้เห็นว่าฟังก์ชันไม่ได้ถูกเริ่มอ่านตั้งแต่ต้นโดยไม่ได้มองข้างล่าง
แต่มีการมองภาพรวมก่อนว่ามีการประกาศตัวแปรภายในนั้นหรือไม่
หากมีการประกาศตัวแปรไหนจะถือว่าตัวแปรนั้นตลอดทั้งขอบเขตในฟังก์ชันนั้นเป็นตัวแปรในฟังก์ชันนั้น
ความเปลี่ยนแปลงที่เกิดกับค่าที่ใช้เป็นอาร์กิวเมนต์ในฟังก์ชัน
ปกติค่าที่ถูกใส่เป็นอาร์กิวเมนต์ให้กับฟังก์ชันจะถูกนำไปแทนเป็นพารามิเตอร์ในฟังก์ชัน
แต่ก็ไม่ใช่ว่าค่าที่ถูกป้อนให้นั้นถือเป็นตัวเดียวกัน
ดังนั้นต่อให้เอาตัวแปรนั้นไปทำอะไรใหม่ก็ไม่ทำให้ตัวแปรเดิมที่เป็นอาร์กิวเมนต์มีความเปลี่ยนแปลงไปด้วย
เช่น
var f = function(x) {
x = x+1;
alert(x); // ได้ 1
};
var a = 0;
f(a);
alert(a); // ได้ 0
จะเห็นว่าฟังก์ชันนี้รับ a ไปเป็นอาร์กิวเมนต์ และถูกแทนลงพารามิเตอร์ x จากนั้น
x ก็ถูกบวกขึ้นอีก 1 แต่การเปลี่ยนแปลงตรงนี้เป็นการป้อนค่าใหม่ให้กับตัวแปร x
ทำให้กลายเป็นคนละตัวกับ a ที่เป็นอาร์กิวเมนต์
ดังนั้นการเปลี่ยนแปลงนี้จึงไม่ได้ส่งผลให้ a เปลี่ยนแปลงไปด้วย
แต่ว่าผลจะต่างออกไป หากอาร์กิวเมนต์นั้นเป็นออบเจ็กต์
และการเปลี่ยนแปลงนั้นเกิดขึ้นที่พรอเพอร์ตีของออบเจ็กต์ เช่น
var hai5baht = function(k) {
alert("มีเหรียญ 5 อยู่ " + k.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 1 เหรียญ
k.rian5 = k.rian5 + 1;
alert("มีเหรียญ 5 อยู่ " + k.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 2 เหรียญ
};
var krapaotang = { rian5: 1, rian10: 6 };
hai5baht(krapaotang);
alert("มีเหรียญ 5 อยู่ " + krapaotang.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 2 เหรียญ
กรณีแบบนี้สิ่งที่เกิดขึ้นก็คือ krapaotang
ถูกส่งไปเป็นอาร์กิวเมนต์ให้กับพารามิเตอร์ k เมื่อพรอเพอร์ตีของ k ถูกแก้ค่า
พรอเพอร์ตีของ krapaotang จึงเปลี่ยนแปลงไปด้วย เพราะถือเป็นออบเจ็กต์เดียวกัน
อย่างไรก็ตาม
หากเปลี่ยนเป็นเขียนแบบนี้จะเท่ากับเป็นการสร้างออบเจ็กต์ใหม่ทับตัวแปร k เดิม
แบบนี้จะไม่มีผลต่อ krapaotang
var hai5baht = function(k) {
alert("มีเหรียญ 5 อยู่ " + k.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 1 เหรียญ
k = { rian5: k.rian5 + 1 };
alert("มีเหรียญ 5 อยู่ " + k.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 2 เหรียญ
};
var krapaotang = { rian5: 1, rian10: 6 };
hai5baht(krapaotang);
alert("มีเหรียญ 5 อยู่ " + krapaotang.rian5 + " เหรียญ"); // ได้ มีเหรียญ 5 อยู่ 1 เหรียญ
ตรงนี้เป็นส่วนที่ต้องค่อยๆทำความเข้าใจให้ดีเพื่อจะได้ไม่เกิดข้อผิดพลาดที่ไม่คาดคิด