ตั้งค่าพารามิเตอร์เริ่มต้นสำหรับฟังก์ชั่น JavaScript


2366

ฉันต้องการให้ฟังก์ชัน JavaScript มีอาร์กิวเมนต์ที่เป็นทางเลือกซึ่งฉันตั้งเป็นค่าเริ่มต้นซึ่งจะถูกใช้หากไม่ได้กำหนดค่า (และจะข้ามหากค่านั้นผ่านไป) ใน Ruby คุณสามารถทำสิ่งนี้ได้:

def read_file(file, delete_after = false)
  # code
end

ใช้งานได้กับ JavaScript หรือไม่

function read_file(file, delete_after = false) {
  // Code
}

คำตอบ:


3296

จากES6 / ES2015พารามิเตอร์เริ่มต้นอยู่ในข้อกำหนดภาษา

function read_file(file, delete_after = false) {
  // Code
}

เพิ่งได้ผล

การอ้างอิง: พารามิเตอร์เริ่มต้น - MDN

พารามิเตอร์ฟังก์ชั่นเริ่มต้นอนุญาตให้พารามิเตอร์อย่างเป็นทางการที่จะเริ่มต้นด้วยค่าเริ่มต้นหากไม่มีค่าหรือไม่ได้กำหนดจะถูกส่งผ่าน

นอกจากนี้คุณยังสามารถจำลองพารามิเตอร์ที่มีชื่อเริ่มต้นผ่านการทำลายล้าง :

// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
    // Use the variables `start`, `end` and `step` here
    ···
}

Pre ES2015 ,

มีหลายวิธี แต่นี่เป็นวิธีที่ฉันชอบ - มันช่วยให้คุณผ่านทุกสิ่งที่คุณต้องการรวมถึงเท็จหรือเป็นโมฆะ ( typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}

216
นอกจากนี้คุณยังสามารถสรุปได้ดังนี้: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }จากนั้นคุณสามารถเรียกมันว่าa = defaultFor(a, 42);
Camilo Martin

6
@SiPlus และคุณได้รับข้อผิดพลาดอ้างอิงเพิ่มเติมโดยไม่เสียค่าใช้จ่ายขณะพยายามใช้undefinedวัตถุ: p แม้ในขณะที่มันอาจทำงานกับเบราว์เซอร์บางตัวและอาจเร็วกว่า แต่nullก็ยังเป็นวัตถุและundefinedอ้างอิงถึงประเภทดั้งเดิมที่พยายามจะบอกว่ามี nullไม่มีอะไรที่นี่ไม่ได้ ดูที่นี่ทั้งสองกรณีสั้น: JavaScript / อ้างอิง / Global_Objects / ไม่ได้กำหนด
Sampo Sarrala - codidact.org

9
ถ้าคุณตรวจสอบกับคุณสมบัติของวัตถุนั้นtypeofซ้ำซ้อน function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }สิ่งนี้จะไม่ทำให้เกิดข้อผิดพลาดในการอ้างอิงและรัดกุม
Dziamid

10
ฉันรู้ว่ามันน้อยมาก แต่ฉันไม่ชอบวิธีที่คุณกำหนดa = aและb = bเมื่อพารามิเตอร์เหล่านั้นไม่ได้ไม่ได้กำหนด นอกจากนี้ผู้ประกอบการที่ประกอบไปด้วยเงื่อนไขที่ซับซ้อนเล็กน้อยอาจอ่านยากสำหรับผู้ดูแลในอนาคต ฉันต้องการไวยากรณ์ต่อไปนี้: if (typeof a == 'undefined') a = 42- ไม่มีการมอบหมายที่ไม่จำเป็นและอ่านง่ายขึ้นเล็กน้อย
Daddy32

12
มีเหตุผลtypeofอะไรบ้างที่จะใช้? a === undefinedมันจะดูเหมือนง่ายที่จะทำ รวมถึงวิธีการที่คุณจะได้รับข้อผิดพลาดอ้างอิงถ้าคุณสะกดผิดundefinedและวางไว้ในสตริง
Abe Voelker

599
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

กำหนดให้นี้delete_afterค่าของdelete_afterถ้ามันไม่ได้เป็นfalsey"my default here"ค่ามิฉะนั้นจะกำหนดสตริง สำหรับรายละเอียดเพิ่มเติมโปรดดูที่การสำรวจดั๊กครอกของภาษาและตรวจสอบส่วนที่เกี่ยวกับผู้ประกอบการ

วิธีนี้ไม่ได้ผลถ้าคุณต้องการที่จะผ่านในfalseyค่าเช่นfalse, null, undefined, หรือ0 ""หากคุณต้องการfalseyค่าที่จะผ่านในการที่คุณจะต้องใช้วิธีการในคำตอบของทอมริท

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

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

ใช้

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 

115
ฉันพบว่าสิ่งนี้ไม่เพียงพอเพราะฉันอาจต้องการผ่านเป็นเท็จ
Tom Ritter

52
ฉันคิดว่ามันเพียงพอแล้วสำหรับสถานการณ์ส่วนใหญ่
Russ Cam

50
เนื่องจากมันไม่ทำงานสำหรับค่าเท็จมันอาจสร้างฝันร้ายบำรุงรักษา บิตของรหัสที่ถูกส่งผ่านค่าความจริงมาก่อนเสมอและล้มเหลวอย่างกระทันหันเนื่องจากรหัสปลอมถูกส่งผ่านเข้ามาควรหลีกเลี่ยงเมื่อมีวิธีการที่แข็งแกร่งกว่านี้
jinglesthula

1
ทำไมในกรณีdelete_afterนี้ไม่ได้ผลลัพธ์แบบบูลdelete_after || "my default value"?
xbonez

3
หรือคุณสามารถเริ่มต้นค่า falsey ซึ่งโดยปกติแล้วจะเป็นค่าเริ่มต้นที่ดีอยู่แล้ว (เช่น false สำหรับ bools สตริงว่างสำหรับสตริง 0 สำหรับตัวเลข ฯลฯ ) - ในกรณีนี้มันไม่สำคัญว่าอะไรจะเกิดขึ้น ผ่านไปแล้ว
Mark Brackett

150

ฉันพบว่าสิ่งที่ง่ายเช่นนี้จะกระชับและสามารถอ่านได้โดยส่วนตัว

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 

6
ปรับปรุง: หากคุณกำลังใช้underscore.js_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});แล้วฉันคิดว่ามันจะดียิ่งขึ้นกับการใช้งาน การใช้เนมสเปซส่วนกลางดังที่แสดงในคำตอบนี้นั้นหลายคนคิดว่าเป็นวิธีปฏิบัติที่ไม่ดี คุณอาจจะลองใช้ยูทิลิตีของคุณเองสำหรับงานทั่วไปนี้ (เช่นutil.default(arg, "defaul value")) หากไม่ต้องการใช้ขีดเส้นใต้ แต่ส่วนใหญ่ฉันจะใช้ขีดเส้นใต้ไม่ช้าก็เร็วไม่ว่าจะในกรณีใดก็ตาม
andersand

2
ฉันแนะนำอันนี้จริง ๆ ฉันใช้แล้วเรียกมันว่า "por" ซึ่งย่อมาจาก "parameter หรือ"
super

2
อย่าพูด typeof arg == 'undefined' แทนที่จะพูด arg === undefined
OsamaBinLogin

3
@OsamaBinLogin สิ่งที่คุณพูดนั้นถูกต้องสำหรับ JS ปัจจุบัน - การทดสอบที่เก่ากว่ายังคงมีอยู่เพราะในบางเบราว์เซอร์ที่เคยเขียนทับundefinedด้วยค่าอื่น ๆ ทำให้การทดสอบล้มเหลว
Alnitak

2
@Alnitak: ยังสามารถแทนที่undefinedได้ ดังนั้นจึงยังคงเป็นความคิดที่ดีที่จะใช้และtypeof 'undefined'
LS

63

ใน ECMAScript 6 คุณจะสามารถเขียนสิ่งที่คุณมี:

function read_file(file, delete_after = false) {
  // Code
}

นี้จะตั้งdelete_afterไปถ้ามันไม่มาประชุมหรือfalse undefinedคุณสามารถใช้คุณลักษณะ ES6 เช่นนี้ในวันนี้ด้วย transpilers เช่นบาเบล

ดูบทความ MDN สำหรับข้อมูลเพิ่มเติม


1
ECMAScript 6 ฉันคิดว่า ... (ฉันจะแก้ไขด้วยตัวเอง แต่ฉันไม่สามารถแก้ไข <6 ตัวอักษร)
Zac

1
รอเบราว์เซอร์ใด ๆ รับ ECMAScript 6
Adriano Resende

1
บาเบลจะทำสิ่งนี้เพื่ออะไร?
harryg


2
นี่คือตารางการทำงานร่วมกันสำหรับ ES6 kangax.github.io/compat-table/es6/#default_function_parametersแต่น่าเสียดายที่รูปแบบนี้ยังไม่รองรับ
freemanoid

27

ค่าพารามิเตอร์เริ่มต้น

ด้วย ES6 คุณสามารถทำหนึ่งในสำนวนที่พบบ่อยที่สุดที่JavaScriptเกี่ยวข้องกับการตั้งค่าเริ่มต้นสำหรับพารามิเตอร์ฟังก์ชั่น วิธีที่เราทำสิ่งนี้มาหลายปีน่าจะคุ้นเคย:

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

รูปแบบนี้ใช้กันมากที่สุด แต่อันตรายเมื่อเราส่งค่าเช่นนั้น

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

ทำไม? เนื่องจาก0 is falsy, และอื่น ๆx || 11 results in 11, ไม่ใช่การส่งผ่านโดยตรงใน 0 เพื่อแก้ไข gotcha นี้, บางคนจะเขียนเช็คแทนแบบละเอียดมากกว่านี้:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

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

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11ในการประกาศฟังก์ชั่นเป็นเหมือนx !== undefined ? x : 11สำนวนสามัญมากกว่าx || 11

นิพจน์ค่าเริ่มต้น

Functionค่าเริ่มต้นสามารถเป็นได้มากกว่าเพียงค่าง่ายๆเช่น 31; พวกเขาสามารถแสดงออกที่ถูกต้องใด ๆ แม้function call:

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

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

การแสดงออกของค่าเริ่มต้นยังสามารถเรียกการแสดงออกของฟังก์ชั่นอินไลน์ - โดยทั่วไปเรียกว่าการแสดงออกฟังก์ชั่นที่เรียกใช้ทันที(IIFE):

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42

13

ทางออกนั้นใช้ได้สำหรับฉันใน js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}

4
เกิดอะไรขึ้นถ้าdelete_afterเป็น0หรือnull? มันจะไม่ทำงานถูกต้องสำหรับกรณีเหล่านี้
Dmitri Pavlutin

@StephanBijzitter มันจะเป็นจริงในบางกรณีเท่านั้น แต่ถ้าคุณต้องการให้ค่าเริ่มต้นเป็น unset ค่าสิ่งนี้ก็ใช้ไม่ได้เพราะ 0 หรือ null! === false
Rutrus

@Rutrus: ฉันไม่เข้าใจสิ่งที่คุณเพิ่งพูด
Stephan Bijzitter

เกี่ยวกับdelete_after = delete_after === undefined ? false : delete_afterอะไร
aashah7

10

เพียงใช้การเปรียบเทียบที่ชัดเจนกับไม่ได้กำหนด

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}

10

ฉันขอแนะนำอย่างระมัดระวังอย่างยิ่งเมื่อใช้ค่าพารามิเตอร์เริ่มต้นใน javascript มันมักจะสร้างข้อผิดพลาดเมื่อใช้ร่วมกับฟังก์ชั่นการสั่งซื้อที่สูงขึ้นเช่นforEach, และmap reduceตัวอย่างเช่นพิจารณาบรรทัดของรหัสนี้:

['1', '2', '3'].map(parseInt); // [1, NaN, NaN]

parseInt มีตัวเลือกพารามิเตอร์ที่สองfunction parseInt(s, [Radix=10])แต่แผนที่สายparseIntที่มีสามข้อโต้แย้ง ( องค์ประกอบ , ดัชนีและอาร์เรย์ )

ฉันขอแนะนำให้คุณแยกพารามิเตอร์ที่ต้องการในรูปแบบอาร์กิวเมนต์ที่เป็นทางเลือก / ค่าเริ่มต้น หากฟังก์ชั่นของคุณใช้พารามิเตอร์ที่ต้องการ 1,2 หรือ 3 ตัวซึ่งไม่มีค่าเริ่มต้นที่สมเหตุสมผลให้ตั้งค่าพารามิเตอร์ตำแหน่งให้กับฟังก์ชันพารามิเตอร์ทางเลือกใด ๆ ที่ควรปฏิบัติตามนั้นเป็นคุณสมบัติที่มีชื่อของวัตถุชิ้นเดียว หากฟังก์ชั่นของคุณใช้เวลา 4 หรือมากกว่าอาจจะเหมาะสมกว่าที่จะให้ข้อโต้แย้งทั้งหมดผ่านคุณสมบัติของพารามิเตอร์วัตถุเดียว

ในกรณีของคุณผมจะแนะนำให้คุณเขียนฟังก์ชั่นของคุณ DeleteFile เช่นนี้ ( แก้ไขต่อ instead 's ความคิดเห็น ) ...

// unsafe
function read_file(fileName, deleteAfter=false) {
    if (deleteAfter) {
        console.log(`Reading and then deleting ${fileName}`);
    } else {
        console.log(`Just reading ${fileName}`);
    }
}

// better
function readFile(fileName, options) {
  const deleteAfter = !!(options && options.deleteAfter === true);
  read_file(fileName, deleteAfter);
}

console.log('unsafe...');
['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);

console.log('better...');
['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);

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


1
"วิธีแก้ปัญหาที่ดีกว่า" นี้อ่านไม่ได้เลยทีเดียว ฉันอยากจะแนะนำให้ตรวจสอบประเภทตัวแปรเช่นtypeof deleteAfter === 'bool'และโยนข้อยกเว้นเป็นอย่างอื่น นอกจากนี้ในกรณีที่ใช้วิธีการเช่น map / foreach เป็นต้นเพียงแค่ใช้ด้วยความระมัดระวังและตัดฟังก์ชั่นที่เรียกว่าพร้อมฟังก์ชั่นที่ไม่ระบุชื่อ ['1', '2', '3'].map((value) => {read_file(value);})
แทน

นั่นเป็นจุดที่ดี ฉันพยายามหลีกเลี่ยงการใช้ไลบรารีในโค้ดของฉัน แต่สำนวนนี้ค่อนข้างยุ่งในจาวาสคริปต์ที่บริสุทธิ์ โดยส่วนตัวฉันจะใช้getวิธีของ lodash เพื่อดึง deleteAfter โยนข้อยกเว้นหากtypeof 'deleteAfter' !== 'bool'อาจเป็นมาตรการที่รอบคอบดี ฉันไม่ชอบวิธีการออกแบบที่ต้องการให้ผู้โทร "ใช้ความระมัดระวัง" ข้อควรระวังเป็นความรับผิดชอบของฟังก์ชั่นไม่ใช่ผู้โทร พฤติกรรมที่สิ้นสุดควรเป็นไปตามหลักการของความประหลาดใจน้อยที่สุด
Doug Coburn

ฉันเห็นด้วยว่าวิธีการนั้นไม่ควรเขียนในแบบที่เรียกว่ามันสามารถทำลายพฤติกรรมของมันได้ แต่โปรดจำไว้ว่าฟังก์ชั่นนั้นเหมือนรุ่นและตัวเรียกก็เหมือนกับตัวควบคุม ตัวแบบควรดูแลการประมวลผลข้อมูล ฟังก์ชั่น (วิธีการ) ควรคาดหวังว่าข้อมูลสามารถส่งผ่านทางที่ผิดและจัดการกับมัน นั่นเป็นเหตุผลที่การตรวจสอบชนิดของพารามิเตอร์รวมถึงการยกเว้นข้อผิดพลาดเป็นวิธีที่ดีที่สุด แม้ว่ามันจะซับซ้อนกว่า แต่ก็ยังสามารถช่วยคุณในการเกาหัวและถามต่อไป ... ทำไมมันไม่ทำงาน! แล้ว ... ทำไมมันถึงทำงาน?
แทน

9

ในฐานะที่เป็นอัปเดต ... กับ ECMAScript 6 คุณสามารถFINALLYค่าเริ่มต้นตั้งอยู่ในฟังก์ชั่นการประกาศพารามิเตอร์ต้องการเพื่อ:

function f (x, y = 7, z = 42) {
  return x + y + z
}

f(1) === 50

ตามที่อ้างอิงโดย - http://es6-features.org/#DefaultParameterValues


11
คำตอบนี้ไม่มีประโยชน์เพราะเป็นคำซ้ำ
ผู้ใช้

8

การเป็นนักพัฒนา C ++ มานาน (หน้าใหม่สู่การพัฒนาเว็บ :)) เมื่อฉันเจอสถานการณ์นี้ครั้งแรกฉันได้ทำการกำหนดพารามิเตอร์ในการกำหนดฟังก์ชั่นเหมือนกับที่กล่าวถึงในคำถามดังต่อไปนี้

function myfunc(a,b=10)

แต่ระวังว่ามันจะไม่ทำงานอย่างสม่ำเสมอในเบราว์เซอร์ สำหรับฉันมันใช้งานได้กับ chrome บนเดสก์ท็อปของฉัน แต่ไม่ได้ทำงานกับ chrome บน android ตัวเลือกที่ปลอดภัยกว่าที่หลายคนกล่าวไว้ข้างต้นคือ -

    function myfunc(a,b)
    {
    if (typeof(b)==='undefined') b = 10;
......
    }

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


3
การกำหนดภายในนิยามฟังก์ชันยังไม่ทำงานใน IE 11 ซึ่งเป็น IE เวอร์ชันล่าสุดสำหรับ Windows 8.1
DiMono

1
ในกรณีที่ทุกคนสงสัยว่าfunction myfunc(a,b=10)เป็นไวยากรณ์ ES6 มีลิงก์ไปยังตารางความเข้ากันได้ในคำตอบอื่น ๆ
gcampbell

7

สำหรับผู้ที่สนใจให้โค้ดทำงานใน Microsoft Edge ห้ามใช้ค่าเริ่มต้นในพารามิเตอร์ฟังก์ชัน

function read_file(file, delete_after = false) {
    #code
}

ในตัวอย่างนั้น Edge จะมีข้อผิดพลาด "Expecting ')'"

เพื่อหลีกเลี่ยงการใช้งานนี้

function read_file(file, delete_after) {
  if(delete_after == undefined)
  {
    delete_after = false;
  }
  #code
}

ตั้งแต่วันที่ 08 ส.ค. 2559 สิ่งนี้ยังคงเป็นปัญหาอยู่


4

ตามไวยากรณ์

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

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


4
function helloWorld(name, symbol = '!!!') {
    name = name || 'worlds';
    console.log('hello ' + name + symbol);
}

helloWorld(); // hello worlds!!!

helloWorld('john'); // hello john!!!

helloWorld('john', '(>.<)'); // hello john(>.<)

helloWorld('john', undefined); // hello john!!!

helloWorld(undefined, undefined); // hello worlds!!!

4

ใช้สิ่งนี้หากคุณต้องการใช้ECMA6ไวยากรณ์ล่าสุด:

function myFunction(someValue = "This is DEFAULT!") {
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

default function parametersมันถูกเรียกว่า อนุญาตให้พารามิเตอร์ทางการสามารถเริ่มต้นได้ด้วยค่าเริ่มต้นหากไม่มีการส่งค่าหรือไม่ได้กำหนด หมายเหตุ : มันจะไม่ทำงานกับ Internet Explorer หรือเบราว์เซอร์รุ่นเก่า

เพื่อความเข้ากันได้สูงสุดใช้สิ่งนี้:

function myFunction(someValue) {
  someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

ฟังก์ชั่นทั้งสองนั้นมีพฤติกรรมเหมือนกันทุกตัวอย่างเหล่านี้ขึ้นอยู่กับความจริงที่ว่าตัวแปรพารามิเตอร์จะเป็นundefinedหากไม่มีการส่งค่าพารามิเตอร์เมื่อเรียกใช้ฟังก์ชันนั้น


หมายเหตุ: ตามที่ @BlackBeard พูดว่าฟังก์ชั่น (param = value) WONT ใช้งานได้กับ IE ใช้รุ่นที่เข้ากันได้
MagicLAMP

4

ES6:ตามที่กล่าวไว้แล้วในคำตอบส่วนใหญ่ใน ES6 คุณสามารถเริ่มต้นพารามิเตอร์พร้อมค่า


ES5:ส่วนใหญ่ของคำตอบที่ได้รับเพียงพอที่ไม่ดีสำหรับฉันเพราะมีโอกาสที่ฉันอาจจะต้องส่งผ่านค่า falsey เช่น0, nullและundefinedเพื่อฟังก์ชั่น เพื่อตรวจสอบว่าพารามิเตอร์ไม่ได้กำหนดเพราะนั่นคือค่าที่ฉันผ่านแทนไม่ได้กำหนดเนื่องจากไม่ได้ถูกกำหนดเลยฉันทำสิ่งนี้:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}

3

function throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}

นี่ foo () เป็นฟังก์ชั่นที่มีพารามิเตอร์ชื่อ argValue หากเราไม่ผ่านสิ่งใดในการเรียกใช้ฟังก์ชันที่นี่ดังนั้นฟังก์ชัน throwIfNoValue () จะถูกเรียกและผลลัพธ์ที่ส่งคืนจะถูกกำหนดให้กับอาร์กิวเมนต์ argValue เท่านั้น นี่คือวิธีการเรียกใช้ฟังก์ชันสามารถใช้เป็นพารามิเตอร์เริ่มต้น ซึ่งทำให้รหัสง่ายขึ้นและอ่านง่ายขึ้น

ตัวอย่างนี้นำมาจากที่นี่


3

หากคุณใช้ES6+คุณสามารถตั้งค่าพารามิเตอร์เริ่มต้นในลักษณะดังต่อไปนี้:

function test (foo = 1, bar = 2) {
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

หากคุณต้องการES5ไวยากรณ์คุณสามารถทำมันในลักษณะดังต่อไปนี้:

function test(foo, bar) {
  foo = foo || 2;
  bar = bar || 0;
  
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

ในไวยากรณ์ข้างต้นORจะใช้โอเปอเรเตอร์ ORประกอบการเสมอกลับค่าแรกว่านี้สามารถแปลงไปtrueหากไม่ได้ก็จะส่งกลับค่า righthandside เมื่อฟังก์ชั่นถูกเรียกโดยไม่มีอาร์กิวเมนต์ที่สอดคล้องกันตัวแปรพารามิเตอร์ ( barในตัวอย่างของเรา) จะถูกตั้งค่าundefinedโดยเอ็นจิน JS undefinedถูกแปลงเป็นเท็จแล้วORผู้ประกอบการจึงส่งกลับค่า 0


3

ใช่การใช้พารามิเตอร์เริ่มต้นได้รับการสนับสนุนอย่างสมบูรณ์ในES6 :

function read_file(file, delete_after = false) {
  // Code
}

หรือ

const read_file = (file, delete_after = false) => {
    // Code
}

แต่ก่อนหน้าในES5คุณสามารถทำสิ่งนี้ได้อย่างง่ายดาย:

function read_file(file, delete_after) {
  var df = delete_after || false;
  // Code
}

ซึ่งหมายความว่าหากมีค่าให้ใช้ค่ามิฉะนั้นใช้ค่าที่สองหลังจาก||การดำเนินการซึ่งทำสิ่งเดียวกัน ...

หมายเหตุ:นอกจากนี้ยังมีความแตกต่างอย่างมากระหว่างสิ่งเหล่านี้หากคุณส่งค่าไปยังES6แม้แต่ค่าที่ผิดพลาดซึ่งจะถูกแทนที่ด้วยค่าใหม่สิ่งที่ชอบnullหรือ""... แต่ES5หนึ่งจะถูกแทนที่หากเพียงค่าที่ส่งผ่าน เป็นความจริงนั่นเป็นเพราะวิธี||การทำงาน ...


2

หากมีเหตุผลบางอย่างที่คุณเป็นไม่ได้ใน ES6 และจะใช้lodashที่นี่เป็นวิธีที่รัดกุมเพื่อเริ่มต้นพารามิเตอร์ฟังก์ชั่นผ่านทาง_.defaultToวิธีการ:

var fn = function(a, b) {
  a = _.defaultTo(a, 'Hi')
  b = _.defaultTo(b, 'Mom!')

  console.log(a, b)
}

fn()                 // Hi Mom!
fn(undefined, null)  // Hi Mom!
fn(NaN, NaN)         // Hi Mom!
fn(1)                // 1 "Mom!"
fn(null, 2)          // Hi 2
fn(false, false)     // false false
fn(0, 2)             // 0 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

ซึ่งจะตั้งค่าเริ่มต้นหากค่าปัจจุบันเป็นNaN , nullหรือไม่ได้กำหนด


1

เสียงแห่งอนาคต

ในอนาคตคุณจะสามารถ "แพร่กระจาย" วัตถุหนึ่งไปยังวัตถุอื่น (ในขณะนี้ในปี 2019 ไม่รองรับ Edge !) - สาธิตวิธีการใช้งานสำหรับตัวเลือกเริ่มต้นที่ดีโดยไม่คำนึงถึงลำดับ:

function test(options) {
    var options = {
       // defaults
       url: 'defaultURL',
       some: 'somethingDefault',
       // override with input options
       ...options
    };
    
    var body = document.getElementsByTagName('body')[0];
    body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

การอ้างอิง MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

... ในขณะที่สิ่งที่Edge DOES รองรับคือ Object.assign () (IE ไม่ได้ แต่ฉันหวังว่าเราจะทิ้ง IE ไว้ข้างหลัง :))

ในทำนองเดียวกันคุณสามารถทำ

    function test(options) {
        var options = Object.assign({
           // defaults
           url: 'defaultURL',
           some: 'somethingDefault',
        }, options); // override with input options
        
        var body = document.getElementsByTagName('body')[0];
        body.innerHTML += '<br>' + options.url + ' : ' + options.some;
    }
    test();
    test({});
    test({url:'myURL'});
    test({some:'somethingOfMine'});
    test({url:'overrideURL', some:'andSomething'});
    test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

แก้ไข:เนื่องจากความคิดเห็นเกี่ยวกับconstตัวเลือก - ปัญหาเกี่ยวกับการใช้ตัวเลือกคงที่ในส่วนที่เหลือของฟังก์ชั่นนั้นจริง ๆ แล้วไม่ใช่ว่าคุณไม่สามารถทำเช่นนั้นได้เพียงว่าคุณไม่สามารถใช้ตัวแปรคงที่ในการประกาศของตัวเอง เพื่อปรับการตั้งชื่ออินพุตให้เป็นอย่างที่ต้องการ

function test(input_options){
   const options = {
     // defaults
     someKey:    'someDefaultValue',
     anotherKey: 'anotherDefaultValue',

     // merge-in input options
     ...input_options
   };

   // from now on use options with no problem
}

ปัญหาคือคุณปกติไม่ต้องการที่จะทำเช่นนี้จะกำหนดตัวเลือกที่กำหนดไว้แล้ว แต่คุณสามารถใช้กับ var อื่น ๆ ที่จะถูกต้อง
frank-dspeed

การทดสอบฟังก์ชั่น (ตัวเลือก) {/ * ตัวเลือกที่กำหนดไว้มันจะโยนข้อผิดพลาดถ้าคุณใช้ตัวเลือก const = {} ตอนนี้ * /}
frank-dspeed

ไม่เป็นสากลเมื่อคุณสร้างฟังก์ชั่นและคุณส่งเป็นตัวเลือกชื่ออาร์กิวเมนต์แล้วภายในตัวเลือกฟังก์ชั่นที่กำหนดไว้ในฟังก์ชั่น (opt) {} opt ถูกกำหนดไว้คุณไม่สามารถใช้ const opt ​​ภายในฟังก์ชั่นนี้ การมอบหมายตัวแปรใหม่หากคุณทำเช่นนั้นบ่อยครั้งและดูเหมือนว่ารูปแบบทั่วไปของคุณนี่เป็นปัญหา
frank-dspeed

@ google-frank-dspeed ah คุณหมายความว่าคุณไม่สามารถทำได้function(opt){ const opt = /*some merging*/; }ใช่ไหม แน่นอนว่าจะไม่ทำงานเพราะคุณจะใช้constตัวแปรก่อนที่จะมีการประกาศ - คุณจะต้องปรับ -function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
jave.web

@ google-frank-dspeed ต่อไปผู้คนใหม่ ๆ อาจจะสงสัยเกี่ยวกับเรื่องนี้มากขึ้นดังนั้นฉันจึงได้เพิ่มโค้ดวิธีการแก้ไข :) ดังนั้นขอขอบคุณที่ชี้ให้คนอื่น ๆ ทราบ :)
38919

1

เพียงเพื่อแสดงทักษะของฉันด้วย (lol) ฟังก์ชั่นด้านบนสามารถเขียนได้โดยไม่ต้องมีการโต้แย้งชื่อดังนี้

ES5 ขึ้นไป

function foo() {
    a = typeof arguments[0] !== 'undefined' ? a : 42;
    b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
    ...
}

ES6 ขึ้นไป

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}

0
def read_file(file, delete_after = false)
  # code
end

รหัสต่อไปนี้อาจทำงานในสถานการณ์เช่นนี้รวม ECMAScript 6 (ES6) เช่นเดียวกับรุ่นก่อนหน้านี้

function read_file(file, delete_after) {
    if(delete_after == undefined)
        delete_after = false;//default value

    console.log('delete_after =',delete_after);
}
read_file('text1.txt',true);
read_file('text2.txt');

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


0

ใช่สิ่งนี้เรียกว่าพารามิเตอร์เริ่มต้น

พารามิเตอร์ฟังก์ชั่นเริ่มต้นอนุญาตให้พารามิเตอร์อย่างเป็นทางการที่จะเริ่มต้นด้วยค่าเริ่มต้นหากไม่มีค่าหรือไม่ได้กำหนดจะถูกส่งผ่าน

ไวยากรณ์:

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

รายละเอียด:

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

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

ด้วยพารามิเตอร์เริ่มต้นใน ES2015 การตรวจสอบในตัวฟังก์ชันไม่จำเป็นอีกต่อไป ตอนนี้คุณก็สามารถใส่ค่าเริ่มต้นในหัวของฟังก์ชั่น

ตัวอย่างของความแตกต่าง:

// OLD METHOD
function multiply(a, b) {
  b = (typeof b !== 'undefined') ?  b : 1;
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5


// NEW METHOD
function multiply(a, b = 1) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5

ตัวอย่างไวยากรณ์ที่แตกต่างกัน

การเติมเต็มไม่ได้กำหนดเทียบกับค่าเท็จอื่น ๆ :

แม้ว่าค่าจะถูกตั้งค่าอย่างชัดเจนเมื่อมีการโทรค่าของอาร์กิวเมนต์ num ก็คือค่าเริ่มต้น

function test(num = 1) {
  console.log(typeof num);
}

test();          // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)

// test with other falsy values:
test('');        // 'string' (num is set to '')
test(null);      // 'object' (num is set to null)

ประเมินเมื่อเวลาโทร:

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

function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], not [1, 2]


// This even applies to functions and variables
function callSomething(thing = something()) {
 return thing;
}

function something() {
  return 'sth';
}

callSomething();  //sth

พารามิเตอร์เริ่มต้นสามารถใช้ได้กับพารามิเตอร์เริ่มต้นในภายหลัง:

พบพารามิเตอร์ที่มีอยู่แล้วในพารามิเตอร์เริ่มต้นในภายหลัง

function singularAutoPlural(singular, plural = singular + 's',
                        rallyingCry = plural + ' ATTACK!!!') {
  return [singular, plural, rallyingCry];
}

//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural('Gecko');

//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural('Fox', 'Foxes');

//["Deer", "Deer", "Deer ... change."]
singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \ petition the government for positive change.')

ฟังก์ชั่นที่กำหนดไว้ภายในฟังก์ชั่นร่างกาย:

แนะนำใน Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30) ฟังก์ชั่นที่ประกาศในร่างกายของฟังก์ชั่นไม่สามารถอ้างถึงภายในพารามิเตอร์เริ่มต้นและโยน ReferenceError (ปัจจุบัน TypeError ใน SpiderMonkey ดูข้อผิดพลาด 1022967) พารามิเตอร์เริ่มต้นจะดำเนินการก่อนเสมอการประกาศฟังก์ชั่นภายในร่างกายฟังก์ชั่นประเมินหลังจากนั้น

// Doesn't work! Throws ReferenceError.
function f(a = go()) {
  function go() { return ':P'; }
}

พารามิเตอร์ที่ไม่มีค่าดีฟอลต์หลังจากพารามิเตอร์ดีฟอลต์:

ก่อนหน้า Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) โค้ดต่อไปนี้ส่งผลให้เกิด SyntaxError สิ่งนี้ได้รับการแก้ไขในข้อผิดพลาด 777060 และทำงานได้ตามที่คาดไว้ในรุ่นที่ใหม่กว่า พารามิเตอร์ยังคงตั้งค่าจากซ้ายไปขวาเขียนทับพารามิเตอร์เริ่มต้นแม้ว่าจะมีพารามิเตอร์ในภายหลังโดยไม่มีค่าเริ่มต้น

function f(x = 1, y) {
  return [x, y];
}

f(); // [1, undefined]
f(2); // [2, undefined]

พารามิเตอร์แบบทำลายที่มีการกำหนดค่าเริ่มต้น:

คุณสามารถใช้การกำหนดค่าเริ่มต้นด้วยรูปแบบการมอบหมายการทำลายโครงสร้าง

function f([x, y] = [1, 2], {z: z} = {z: 3}) {
  return x + y + z;
}

f(); // 6

0

เพียงวิธีการที่แตกต่างกันในการตั้งค่าพารามิเตอร์เริ่มต้นคือการใช้วัตถุแผนที่ของการขัดแย้งแทนการขัดแย้งโดยตรง ตัวอย่างเช่น,

const defaultConfig = {
 category: 'Animals',
 legs: 4
};

function checkOrganism(props) {
 const category = props.category || defaultConfig.category;
 const legs = props.legs || defaultConfig.legs;
}

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


-1

คำตอบคือใช่ ในความเป็นจริงมีหลายภาษาที่ให้การสนับสนุนค่าเริ่มต้น Python เป็นหนึ่งในนั้น:

def(a, enter="Hello"):
   print(a+enter)

แม้ว่านี่คือรหัส Python 3 เนื่องจากวงเล็บพารามิเตอร์เริ่มต้นในฟังก์ชั่นยังทำงานใน JS

ตัวอย่างเช่นและในกรณีของคุณ:

function read_file(file, deleteAfter=false){
  console.log(deleteAfter);
}

read_file("test.txt");

แต่บางครั้งคุณไม่ต้องการพารามิเตอร์เริ่มต้น

คุณสามารถกำหนดตัวแปรได้ทันทีหลังจากเริ่มฟังก์ชั่นดังนี้

function read_file(file){
  var deleteAfter = false;
  console.log(deleteAfter);
}

read_file("test.txt");

ในตัวอย่างทั้งสองของฉันมันส่งคืนสิ่งเดียวกัน แต่บางครั้งพวกเขาอาจมีประโยชน์เช่นในโครงการที่ก้าวหน้ามาก

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

แก้ไข:และนี่คือสิ่งสำคัญยิ่ง! สิ่งนี้จะไม่ทำงานใน IE โปรดดูเอกสาร ดังนั้นด้วย IE คุณต้องใช้วิธี "define variable ที่ด้านบนสุดของฟังก์ชั่น" พารามิเตอร์เริ่มต้นจะไม่ทำงานใน IE


-3

ใช่มันจะทำงานใน Javascript คุณยังสามารถทำสิ่งต่อไปนี้

function func(a=10,b=20)
{
    alert (a+' and '+b);
}

func(); // Result: 10 and 20

func(12); // Result: 12 and 20

func(22,25); // Result: 22 and 25

2
ขณะนี้ยังไม่สามารถพกพาได้ ... IE ... developer.mozilla.org/en/docs/Web/JavaScript/Reference/ ...... (และเป็นคำตอบที่ซ้ำกัน ... )
Gert van den Berg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.