φυβλαςのβλογ
phyblas的博客



javascript เบื้องต้น บทที่ ๑๐: การสร้างฟังก์ชัน
เขียนเมื่อ 2019/07/31 23:16
แก้ไขล่าสุด 2021/09/28 16:42
javascript เบื้องต้น บทที่ ๑๐: การสร้างฟังก์ชัน


ความหมายของฟังก์ชัน

คำว่าฟังก์ชัน (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 เหรียญ

ตรงนี้เป็นส่วนที่ต้องค่อยๆทำความเข้าใจให้ดีเพื่อจะได้ไม่เกิดข้อผิดพลาดที่ไม่คาดคิด




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ