จะเกิดอะไรขึ้นถ้าฉันไม่ส่งพารามิเตอร์ในฟังก์ชัน Javascript


90

ฉันยังใหม่กับโลกของ Javascript และกำลังปรับแต่งกับการเขียนฟังก์ชันพื้นฐานและสะดุดกับตัวอย่างด้านล่างโดยบังเอิญและไม่แน่ใจว่าทำไมถึงใช้งานได้เมื่อฉันไม่ส่งพารามิเตอร์เมื่อฟังก์ชันต้องการ

ฟังก์ชั่นตัวอย่าง

function myfunction(x) {
    alert("This is a sample alert");
}

ตอนนี้ถ้าฉันเรียกใช้ฟังก์ชันmyfunction();ฉันจะแสดงการแจ้งเตือน เหตุใดฉันจึงสามารถเรียกใช้ฟังก์ชันได้โดยไม่มีข้อผิดพลาดหรือคำเตือนเมื่อฉันไม่ได้ส่งผ่านพารามิเตอร์

แก้ไข

ฉันไม่ได้คาดหวังคำตอบที่ยอดเยี่ยมมากมายและฉันก็ไม่ได้อยู่ในสถานะที่สามารถพูดได้ว่าคำตอบใดดีที่สุดดังนั้นฉันจึงสามารถขอให้คนอื่นแนะนำคำตอบที่ดีที่สุดและฉันจะให้รางวัลแก่บุคคลนั้น


2
อาจเป็นประโยชน์เช่นกัน: developer.mozilla.org/en/JavaScript/Guide/Functions
Felix Kling

2
ไม่มีการโอเวอร์โหลดตามลายเซ็นฟังก์ชันใน JS ดังนั้นจึงไม่สนใจว่าฟังก์ชัน "คาด" จะมีกี่พารามิเตอร์ คุณสามารถส่งผ่านพารามิเตอร์ที่ฟังก์ชันไม่ได้กำหนดให้ใช้และเพียงแค่ใช้อาร์กิวเมนต์คำหลักเพื่อดึงข้อมูล
scrappedcola

@scrappedcola - คุณหมายถึงอะไรโดยการโอเวอร์โหลดและส่งผ่านพารามิเตอร์ที่ฟังก์ชันไม่ได้กำหนดให้ใช้? คุณสามารถยกตัวอย่างได้หรือไม่?
PeanutsMonkey

2
@PeanutsMonkey. เขาหมายความว่าคุณไม่สามารถมีสองฟังก์ชัน: function foo(x){...}และfunction foo(x,y,z){...}คุณสามารถมีได้เพียงฟังก์ชันเดียวสำหรับแต่ละชื่อ
gdoron ให้การสนับสนุน Monica

2
@PeanutsMonkey. ใช่คุณไม่มีfunction overloadingใน js คุณมีวิธีอื่นในการล้อเลียน
gdoron สนับสนุน Monica

คำตอบ:


114

จะไม่มีอะไรเกิดขึ้น - หมายความว่าคุณจะไม่ได้รับข้อผิดพลาดหรือคำเตือนเนื่องจากการส่งพารามิเตอร์ในจาวาสคริปต์เป็นทางเลือก
ทุกพารามิเตอร์ที่ไม่ได้ถูก "ที่จัด" จะมีค่าundefined

function foo(x, y, z){
    //...
}

foo(1);

ภายในfooฟังก์ชั่นตอนนี้:

function foo(x, y, z){
    x === 1
    y === undefined
    z === undefined
}

คุณสามารถส่งผ่านข้อโต้แย้งได้มากขึ้นเช่น:

foo(1,2,3,4,5,7); // Valid!

คุณสามารถทราบจำนวนพารามิเตอร์ที่arguments.lengthมาจากภายในฟังก์ชัน

function foo(x, y, z) {
    console.log('x value: ' + x);
    console.log('y value: ' + y);
    console.log('z value: ' + z);
    console.log('Arguments length: ' + arguments.length);
}
console.log('Zero parameters');
foo();
console.log('Four parameters');
foo(1, 2, 3, 4);

ตัวอย่างฟังก์ชันที่มีประโยชน์ที่จัดการพารามิเตอร์จำนวนเท่าใดก็ได้:

function max() {
    var maxValue = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        if (maxValue < arguments[i]) {
            maxValue = arguments[i];
        }
    }
    return maxValue;
}

alert(max(1, 5, 7, 2, 88, 32, 44));


ขอบคุณสำหรับการสาธิตสด ไม่ได้คาดหวังคำตอบที่ดีมากมาย ดังนั้นถ้าฉันมีฟังก์ชันเช่นfunction myfunction (a,b){}และส่งผ่านค่า my function (1,2,3,4,5) ฉันก็ถือว่ามันยังใช้ได้อยู่? เป็นความคาดหวังว่าจะมีคำเตือนหรือข้อผิดพลาดบางอย่างหรือไม่?
PeanutsMonkey

ขอโทษconsole.logค่ะคุณช่วยอธิบายรายละเอียดเกี่ยวกับสิ่งที่คำสั่งทำเช่นเดียวกับ arguments.length ได้ไหม
PeanutsMonkey

@PeanutsMonkey. ถูกต้อง! ไม่มีคำเตือนไม่มีข้อผิดพลาดมันมีประโยชน์ฉันจะสาธิตให้คุณดูในอีกสักครู่
gdoron สนับสนุน Monica

1
@PeanutsMonkey. มันทำงานร่วมกับ IE ได้เช่นกันหากคุณติดตั้งคอนโซลนักพัฒนาฉันคิดว่ามันถูกติดตั้งโดยค่าเริ่มต้นจาก IE8 + alertผมไม่เข้าใจสิ่งที่คุณเขียนเกี่ยวกับ
gdoron ให้การสนับสนุน Monica

1
@PeanutsMonkey. 1.คุณไม่สามารถมีรหัสได้หลังจากที่returnถูกละเว้น 2.คุณจะไม่ได้รับข้อผิดพลาดหรือคำเตือน ดูการสาธิตนี้
gdoron สนับสนุน Monica

10

อาร์กิวเมนต์ทั้งหมดในฟังก์ชัน JavaScript เป็นทางเลือก (อ่านว่า "พิมพ์ผิด")

ฟังก์ชัน JavaScript สามารถเรียกใช้ด้วยอาร์กิวเมนต์จำนวนเท่าใดก็ได้โดยไม่คำนึงถึงจำนวนอาร์กิวเมนต์ที่ตั้งชื่อในนิยามฟังก์ชัน เนื่องจากฟังก์ชันถูกพิมพ์แบบหลวม ๆ จึงไม่มีทางที่ฟังก์ชันจะประกาศประเภทของอาร์กิวเมนต์ที่ต้องการได้และการส่งผ่านค่าประเภทใด ๆ ไปยังฟังก์ชันใด ๆ ก็เป็นไปตามกฎหมาย เมื่อมีการเรียกใช้ฟังก์ชันโดยมีอาร์กิวเมนต์น้อยกว่าที่ประกาศไว้อาร์กิวเมนต์เพิ่มเติมจะมีค่าที่ไม่ได้กำหนดไว้

คุณสามารถอ้างถึงอาร์กิวเมนต์ของฟังก์ชันภายในฟังก์ชันได้โดยใช้ตัวแปรอาร์กิวเมนต์ที่มีชื่อหรืออ็อบเจ็กต์อาร์กิวเมนต์ วัตถุนี้มีรายการสำหรับแต่ละอาร์กิวเมนต์ที่ส่งไปยังฟังก์ชันดัชนีของรายการแรกเริ่มต้นที่ 0 ตัวอย่างเช่นถ้าฟังก์ชันถูกส่งผ่านสามอาร์กิวเมนต์คุณสามารถอ้างถึงอาร์กิวเมนต์ได้ดังนี้:

arguments[0]
arguments[1]
arguments[2]
  • JavaScript - The Definitive Guide, 5th Edition

7

นั่นเป็นเพียงวิธีการทำงานของ JavaScript พารามิเตอร์เป็นทางเลือกและจะมีค่าที่ไม่เป็นค่าจริง "ไม่ได้กำหนด" ในฟังก์ชันหากพารามิเตอร์เหล่านี้ขาดหายไปจากการเรียกใช้ฟังก์ชัน

โดย "ไม่บังคับ" ฉันหมายถึงอย่างนั้น: การเรียกใช้ฟังก์ชันใด ๆเกี่ยวข้องกับรายการพารามิเตอร์ที่ยาวตามอำเภอใจ มีความจำเป็นต้องไม่มีความสัมพันธ์ระหว่างจำนวนของพารามิเตอร์ที่ส่งผ่านไปยังฟังก์ชันและจำนวนประกาศ วิธีที่ดีที่สุดในการนึกถึงคำประกาศนี้แล้ว:

function x(a, b, c) {
  // ...
}

คือคุณกำลังประกาศฟังก์ชันและผูกชื่อ "a" กับพารามิเตอร์ตัวแรก "b" กับพารามิเตอร์ตัวที่สองและ "c" กับตัวที่สาม มันไม่ได้หมายความว่าการรับประกัน แต่ที่ใด ๆ ของเหล่านั้นจะจริงจะผูกพันกับค่าในการอุทธรณ์ใด ๆ ของการทำงานในภายหลัง

ด้วยโทเค็นเดียวกันคุณสามารถกำหนดฟังก์ชันโดยไม่ต้องมีพารามิเตอร์ใด ๆ เลยจากนั้น "ค้นหา" ผ่านargumentsอ็อบเจกต์:

function noArgs() {
  var a = arguments[0], b = arguments[1], c = arguments[2];
  // ...
}

ดังนั้นที่ไม่ค่อนข้างเช่นเดียวกับฟังก์ชั่นแรก แต่มันใกล้มากที่สุดในรูปแบบที่นับได้ในทางปฏิบัติ

ค่า "ไม่ได้กำหนด" ใน JavaScript เป็นค่า แต่ความหมายเป็นค่าที่ผิดปกติเมื่อใช้ภาษา โดยเฉพาะอย่างยิ่งมันไม่เหมือนกับnullค่า นอกจากนี้ "ไม่ได้กำหนด" เองก็ไม่ใช่คำหลัก มันเป็นแค่ชื่อตัวแปรกึ่งพิเศษ!


คุณสามารถทำอย่างละเอียดต่อไปสิ่งที่คุณหมายถึงoptionalเช่นเดียวกับ "ไม่ได้จริงๆค่า" คุ้มค่าundefined?
PeanutsMonkey

@PeanutsMonkey - undefinedถ้าตัวแปรที่ไม่ได้รับแล้วก็จะเป็น
Derek 朕會功夫

@Pointy - คุณหมายถึงอะไรโดยไม่มีการรับประกันว่าพารามิเตอร์ที่ประกาศใด ๆ จะถูกผูกไว้กับค่าจริง ๆ ?
PeanutsMonkey

1
@PeanutsMonkey JavaScript เป็นภาษาแบบไดนามิก เมื่อเรียกใช้ฟังก์ชันการประกาศฟังก์ชันไม่สำคัญรวมถึงจำนวนพารามิเตอร์ ดังนั้นคุณสามารถประกาศฟังก์ชันที่มีพารามิเตอร์ได้มากเท่าที่คุณต้องการ แต่จะไม่มีข้อ จำกัด เกี่ยวกับจำนวนพารามิเตอร์ที่ส่งผ่านจริงเมื่อฟังก์ชันของคุณถูกเรียกใช้ (ในแบบที่มันเรียงลำดับของเช่น C, C อย่างน้อยในวันเก่า.) ดังนั้นหากคุณประกาศพารามิเตอร์และสายทำโดยไม่ต้องค่าพารามิเตอร์ใด ๆ undefinedที่จัดพารามิเตอร์จะ
Pointy

3

JavaScript ไม่มีค่าเริ่มต้นสำหรับพารามิเตอร์ฟังก์ชันเหมือนภาษาอื่น ๆ ดังนั้นคุณสามารถส่งผ่านข้อโต้แย้งได้มากหรือน้อยเท่าที่คุณต้องการ

undefinedถ้าคุณไม่ผ่านค่าพารามิเตอร์

function myfunction(x) {
    alert(x);
}

myfunction(); // alerts undefined
myfunction(1); // alerts 1
myfunction(1,2,3); // alerts 1

argumentsหากคุณส่งผ่านพารามิเตอร์มากกว่าที่มีอยู่ในลายเซ็นคุณสามารถใช้

function myfunction(x) {
    alert(x);
    console.log(arguments);
}

myfunction(1,2,3); // alerts 1, logs [1,2,3]

ขอบคุณ. แทนที่จะโพสต์ข้ามโปรดดูตัวอย่างของฉันที่ฉันให้กับ David Thomas ได้undefined
ไหม

@PeanutsMonkey: หือ? ปัญหาของคุณคืออะไร?
Rocket Hazmat

ไม่ใช่ปัญหาต่อตัว ฉันอ้างถึงคำถามติดตามผลของฉันกับเดวิดเกี่ยวกับการส่งผ่านพารามิเตอร์เพิ่มเติมซึ่งคุณได้รวมไว้ในคำตอบ สิ่งที่ฉันไม่ค่อยตามคือสิ่งที่คุณหมายถึงlogs? มันบันทึกไว้ที่ไหน?
PeanutsMonkey

1
@PeanutsMonkey: บันทึกลงใน "คอนโซล JavaScript" ของคุณ ในเบราว์เซอร์ส่วนใหญ่คุณสามารถกดF12หรือCtrl+Shift+Jเพื่อเข้าถึงได้
Rocket Hazmat

1
ประโยคแรกล้าสมัย ณES2015 ...
Heretic Monkey

2

คุณยังสามารถระบุอาร์กิวเมนต์ได้มากกว่าอาร์กิวเมนต์ที่กล่าวถึงในฟังก์ชัน

myFunction(1,2,3,4,5,6,7,'etc');

คุณสามารถใช้argumentsคุณสมบัติซึ่งเป็นอาร์เรย์เพื่อดูอาร์กิวเมนต์ที่ให้มา


@albert ข้อโต้แย้งไม่ได้เป็น array array เช่นวัตถุที่เห็น
Mahi

1

เนื่องจากไม่มีข้อผิดพลาดจนกว่าฟังก์ชันคาดว่าจะสามารถทำงานกับพารามิเตอร์ที่คุณควรจะส่งผ่าน

ตัวอย่างเช่น:

function myfunction(x) {
    return x*2;
}

จะทำให้เกิดข้อผิดพลาด; แม้ว่าอาจจะเป็นเพียงNaN(ในกรณีนี้) หรือกvariable is undefined.


โอเคตราบใดที่ฉันไม่อ้างอิงพารามิเตอร์ในฟังก์ชันฉันจะไม่ได้รับข้อผิดพลาด? นั่นถูกต้องใช่ไหม?
PeanutsMonkey

ตอนนี้ถ้าฉันอธิบายรายละเอียดเกี่ยวกับตัวอย่างที่คุณระบุเช่นfunction myfunction(a,b) { var calc = a+b; return;}แล้วเรียกใช้ฟังก์ชันdocument.write(myfunction(1.2));เหตุใดฉันจึงยังคงได้รับค่าundefinedแม้ว่าฉันจะส่งผ่านพารามิเตอร์
PeanutsMonkey

1
เพราะคุณไม่ได้ส่งคืนอะไรเลย ในตัวอย่างของคุณคุณต้องส่งคืนค่าอย่างใดอย่างหนึ่งอย่างชัดเจน : อย่างใดอย่างหนึ่งreturn calc;หรือreturn a+b;(เป็นบรรทัดสุดท้ายอย่างชัดเจนและค่าหลังreturnแทนที่var calc)
เดวิดกล่าวว่าคืนสถานะโมนิกา

คุณหมายความว่าฉันไม่ต้องประกาศตัวแปรถ้าฉันทำreturn a+b;?
PeanutsMonkey

@PeanutsMonkey - คุณสามารถอ่านเพิ่มเติมได้ที่นี่return
Derek 朕會功夫

0

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

คุณสมบัติอีกประการหนึ่งคือความสามารถในการกำหนดฟังก์ชันโดยไม่มีพารามิเตอร์และเรียกใช้ด้วยอาร์กิวเมนต์ได้สำเร็จโดยใช้ประโยชน์จากargumentsวัตถุ ซึ่งช่วยให้คุณสร้างอาร์เรย์อาร์กิวเมนต์ที่มีความยาวผันแปรได้อย่างง่ายดาย


0

ใน javascript console.log ภายในฟังก์ชันจะให้ undefined เป็นเอาต์พุตสำหรับพารามิเตอร์ที่ไม่ผ่าน แต่ภายนอกฟังก์ชันจะไม่ได้กำหนดข้อผิดพลาดไว้ภายในฟังก์ชันเบราว์เซอร์จะประกาศตัวแปรอย่างชัดเจน สำหรับเช่น

console.log(x) 

ให้ VM1533: 1 Uncaught ReferenceError: x ไม่ได้กำหนดไว้ในขณะที่

function test(x) {
console.log(x)
}
test(); 

ให้ไม่ได้กำหนด เป็นเพราะการทดสอบฟังก์ชัน () ถูกเขียนใหม่โดยเบราว์เซอร์เป็น:

function test(x) {
    var x;
    console.log(x)
    }

ตัวอย่างอื่น : -

var x =5 ;
function test(x) {
console.log(x)
}
test(); 

ยังไม่ได้กำหนดเมื่อฟังก์ชันกลายเป็น

function test(x) {
    var x;
    console.log(x)
    }

การแจ้งเตือนในตัวอย่างด้านล่างจะไม่ได้กำหนด: -

    var x =5;
    function test() {
    alert(x);
    var x =10;
    }

test(); 

ฟังก์ชันข้างต้นจะกลายเป็น: -

 function test() {
    var x;
    alert(x);
    x =10;
    }

ขอบเขตของตัวแปร javascript ภายในฟังก์ชันคือขอบเขตระดับฟังก์ชันไม่ใช่ระดับบล็อก สำหรับเช่น

function varScope() {

for(var i = 0; i < 10; i++){
    for(var j = 0; j < 5; j++){}
        console.log("j is "+j)
    }
    console.log("i is "+i);


}
varScope();

จะให้ผลลัพธ์เป็น:

j is 5 
i is 10

อีกครั้งฟังก์ชั่นกลายเป็น: -

  function varScope() {
    var i;
    var j;
    for(i = 0; i < 10; i++){
        for(j = 0; j < 5; j++){}
            console.log("j is "+j)
        }
        console.log("i is "+i);
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.