javascript ตั้งค่าตัวแปรหากไม่ได้กำหนด


172

ฉันรู้ว่าฉันสามารถทดสอบตัวแปรจาวาสคริปต์แล้วกำหนดว่ามันไม่ได้กำหนด แต่ไม่มีวิธีการพูดบางอย่าง

var setVariable = localStorage.getItem ('value') || 0;

ดูเหมือนจะเป็นวิธีที่ชัดเจนกว่ามากและฉันค่อนข้างมั่นใจว่าฉันเคยเห็นสิ่งนี้ในภาษาอื่น


30
นั่นไม่ใช่การทดสอบสำหรับ "undefined" แต่เป็นการทดสอบสำหรับ "falsey"
Alnitak

3
โปรดทราบว่าlocalStorage.getItem()จะมีข้อยกเว้นหากผู้ใช้ปิดใช้งานคุกกี้ (อย่างน้อยใน Chrome) ดังนั้นคุณอาจต้องการห่อในส่วนtry...catchคำสั่ง
urish

1
มีความเป็นไปได้ที่ซ้ำกันของการสร้าง x = x || อะไร y หมายถึงอะไร
MichałPerłakowski

คำตอบ:


304

ใช่มันสามารถทำเช่นนั้น แต่อย่างเคร่งครัดพูดที่จะกำหนดค่าเริ่มต้นถ้าค่าที่ดึงมาเป็นfalseyเมื่อเทียบกับอย่างแท้จริงไม่ได้กำหนด มันจะดังนั้นจึงไม่เพียง แต่ตรงundefinedแต่ยังnull, false, 0, NaN, "" ( แต่ไม่ได้ "0" )

หากคุณต้องการตั้งค่าเริ่มต้นเฉพาะในกรณีที่ตัวแปรนั้นเคร่งครัดundefinedวิธีที่ปลอดภัยที่สุดคือการเขียน:

var x = (typeof x === 'undefined') ? your_default_value : x;

ในเบราว์เซอร์ที่ใหม่กว่าการเขียนให้ปลอดภัย:

var x = (x === undefined) ? your_default_value : x;

แต่โปรดระวังว่ามันเป็นไปได้ที่จะทำลายสิ่งนี้บนเบราว์เซอร์รุ่นเก่าที่ได้รับอนุญาตให้ประกาศตัวแปรundefinedที่มีค่าที่กำหนดไว้ทำให้การทดสอบล้มเหลว


3
ฉันประหลาดใจที่รูปแบบนี้ไม่รวมอยู่ใน libs JS เพิ่มเติม
joemaller

จะมีข้อเสียในการใช้เป็นอีกเล็กน้อยvar x = (x === undefined ? def_val : x); var x = (typeof x === 'undefined') ? def_val : x;พฤติกรรมแตกต่างกันหรือไม่?
Marco Pashkov

3
@marco ในเบราว์เซอร์รุ่นเก่าเป็นไปได้undefinedที่จะกำหนดใหม่ทำให้การทดสอบความเท่าเทียมกันล้มเหลว
Alnitak

@Alnitak เป็นวิธีที่ดีที่สุดในการใช้ไวยากรณ์ที่คล้ายกับ OP ที่ใช้อยู่และยังคงตรวจสอบไม่ได้กำหนด?
Ivo Pereira

@IvoPereira คุณไม่สามารถใช้||วิธีในการทดสอบที่เข้มงวดสำหรับการไม่ได้กำหนดคุณต้องใช้การทดสอบที่ชัดเจนสำหรับundefinedเงื่อนไข
Alnitak

26

คำตอบของปี 2018 ES6 คือ :

return Object.is(x, undefined) ? y : x;

หากตัวแปร x ไม่ได้ถูกกำหนดไว้คืนค่าตัวแปร y ... มิฉะนั้นถ้าตัวแปร x ถูกนิยามให้ส่งคืนตัวแปร x


4
เท่าที่ฉันสามารถบอกObject.isได้ไม่มีอะไรดีไปกว่า===ในกรณีนี้ "ตัวดำเนินการ === (และตัวดำเนินการ == ด้วย) ปฏิบัติกับค่าตัวเลข -0 และ +0 เท่ากับและถือว่า Number.NaN ไม่เท่ากับ NaN" ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...... ) ไม่สำคัญเลย
เทรเวอร์ดิกซัน

5
ฉันไม่เห็นด้วย. รู้จักทั้งคู่และใช้อันที่เหมาะสม โดยเฉพาะอย่างยิ่งการใช้งานถ้าทั้งสองตัวถูกดำเนินการอาจจะมีObject.is NaN
Trevor Dixon

2
หาก Object.is () ใช้งานได้ 100% ของเคสการใช้งานและ === ใช้งานได้ 98% ของเคสการใช้งานทำไมคุณถึงเสี่ยงที่จะใช้ === เลย? ตัวอย่างเช่น: console.log (+0 === -0); // เอาต์พุตจริงขณะที่ console.log (Object.is (+0, -0)); // ผลลัพธ์เป็นเท็จ - ไหนดีกว่ากัน? ลบเป็น 0 เหมือนกับบวก 0 หรือไม่ นั่นเป็นคำถามที่คุณต้องถามตัวเอง แต่ถ้าคุณใช้ Object.is () คุณจะรู้คำตอบเสมอ ไม่เหมือนกันดังนั้นเอาต์พุตของ false จึงเป็นผลลัพธ์ที่ถูกต้องและคาดหวัง
Sterling Bourne

2
undefinedบริบทเฉพาะที่นี่อยู่เสมอเมื่อเทียบกับ ดังนั้น===จะทำงานได้ 100% ไม่ใช่แค่ 98% ข้อดีของ===การอ่านง่ายขึ้นโดยเฉพาะอย่างยิ่งสั้นลงและหลีกเลี่ยงการโทรด้วยวิธีที่ไม่จำเป็น ส่วนตัวฉันจะใช้เฉพาะObject.is()เมื่อสถานการณ์ต้องการและต้องการ===ในกรณีอื่น ๆ ทั้งหมด
blubberdiblub

1
แน่นอน; ถ้าคุณเป็น coder ที่มีประสบการณ์ หากคุณลืมเครื่องหมายเท่ากับโดยไม่ตั้งใจซึ่งในกรณีนี้การแก้ไขข้อผิดพลาดทำไม == ไม่ทำงานที่ไหนสักแห่งเป็นสิ่งที่ฉันไม่ต้องการจากนักพัฒนา ปลอดภัยกว่าดีกว่าขออภัยและใช้ Object.is () เสมอเหตุผลที่รวมอยู่ในข้อมูลจำเพาะนั้นโดยเฉพาะเพื่อช่วยให้นักพัฒนาเขียนโค้ดบั๊กกี้น้อยลง
สเตอร์ลิงบอร์น

7

ฉันต้องการ "ตั้งค่าตัวแปรหากไม่ได้กำหนด" ในหลาย ๆ ที่ ฉันสร้างฟังก์ชันโดยใช้ @Alnitak answer หวังว่ามันจะช่วยให้ใครบางคน

function setDefaultVal(value, defaultValue){
   return (value === undefined) ? defaultValue : value;
}  

การใช้งาน:

hasPoints = setDefaultVal(this.hasPoints, true);

6

ดูเหมือนว่ามีเหตุผลมากกว่าที่จะตรวจสอบtypeofแทนundefined? ฉันคิดว่าคุณคาดหวังจำนวนเมื่อคุณตั้ง var เป็น0เมื่อไม่ได้กำหนด:

var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;

ในกรณีนี้หากgetVariableไม่ใช่ตัวเลข (สตริงวัตถุอะไรก็ตาม) setVariable จะถูกตั้งค่าเป็น0


5

ES2020 คำตอบ

ด้วยตัวดำเนินการNullish Coalescingคุณสามารถตั้งค่าเริ่มต้นได้ถ้าvalueว่างหรือไม่ได้กำหนด

const setVariable = localStorage.getItem('value') ?? 0;

อย่างไรก็ตามคุณควรทราบว่าตัวดำเนินการรวมแบบ nullish จะไม่ส่งคืนค่าเริ่มต้นสำหรับค่าความผิดพลาดประเภทอื่นเช่น0และ''และ

โปรดทราบว่าการสนับสนุนเบราว์เซอร์สำหรับผู้ให้บริการมี จำกัด ตามข้อมูลจากcaniuseสนับสนุนเบราว์เซอร์ 48.34% เท่านั้น (จนถึงเมษายน 2563) สนับสนุน Node.js ถูกเพิ่มเข้ามาในรุ่น 14


2

หากคุณเป็นแฟนตัวยงของFP ( ฟังก์ชั่นการเขียนโปรแกรม ) Ramdaมีฟังก์ชั่นตัวช่วยที่เรียบร้อยสำหรับสิ่งนี้เรียกว่าdefaultTo :

การใช้งาน:

const result = defaultTo(30)(value)

มันมีประโยชน์มากขึ้นเมื่อจัดการกับundefinedค่าบูลีน:

const result2 = defaultTo(false)(dashboard.someValue)


1
ตรงconst result = value || 30;นี้ยกเว้นการใช้ฟังก์ชั่น in-between และ +1000 bytes lib
Adelin

1
@Adelin ไม่จริงมันยังจัดการเท็จประเภทบูลีน หากคุณใช้ lib นี้อยู่แล้ว (อย่างที่ฉันเป็น) มันก็มีประโยชน์ทีเดียวและเป็นคำย่อ
Damian Green

1

var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;


จะไม่ asign เป็น 0 ถ้าlocalStorage.getItem('value'))ส่งคืนfalse
Karl Adler

1

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

function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
    if (typeof (value) === 'undefined') {
        return newValue;
    } else if (value === null && overwriteNull === true) {
        return newValue;
    } else if (value === 0 && overwriteZero === true) {
        return newValue;
    } else {
        return value;
    }
}

มันสามารถถูกเรียกใช้พร้อมกับพารามิเตอร์สองตัวสุดท้ายเป็นตัวเลือกถ้าฉันต้องการตั้งค่าที่ไม่ได้กำหนดเท่านั้นหรือเขียนทับค่า null หรือ 0 นี่คือตัวอย่างของการเรียกไปที่จะตั้ง ID เป็น -1 ถ้า ID ไม่ได้กำหนดหรือเป็นโมฆะ แต่จะไม่เขียนทับค่า 0

data.ID = Util.getIfNotSet(data.ID, -1, true);

1

ในสมัยของเราคุณสามารถทำแนวทางของคุณกับ JS:

// Your variable is null
// or '', 0, false, undefined
let x = null;

// Set default value
x = x || 'default value';

console.log(x); // default value

ดังนั้นตัวอย่างของคุณจะทำงาน:

const setVariable = localStorage.getItem('value') || 0;


0

สำหรับฉันดูเหมือนว่าสำหรับการใช้งานจาวาสคริปต์ปัจจุบัน

var [result='default']=[possiblyUndefinedValue]

เป็นวิธีที่ดีในการทำเช่นนี้ (โดยใช้การแยกวัตถุ)


0

การกำหนดตรรกะลอจิกโซลูชัน ES2020 +

ผู้ประกอบการใหม่กำลังถูกเพิ่มเข้าไปในเบราว์เซอร์, ??=, และ||= &&=โพสต์นี้จะมุ่งเน้น??=โพสต์นี้จะมุ่งเน้นไปที่

นี้จะตรวจสอบว่าด้านซ้ายไม่ได้กำหนดหรือเป็นโมฆะการลัดวงจรถ้ากำหนดไว้แล้ว ถ้าไม่ถูกต้องด้านขวาจะถูกกำหนดให้กับตัวแปรด้านซ้าย

วิธีเปรียบเทียบ

// Using ??=
name ??= "Dave"

// Previously, ES2020
name = name ?? "Dave"

// Before that (not equivalent, but commonly used)
name = name || "Dave" // name ||= "Dave"

ตัวอย่างพื้นฐาน

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

// Equivalent to
a = a ?? true

ตัวอย่างวัตถุ / อาร์เรย์

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

?? = การสนับสนุนเบราว์เซอร์กรกฎาคม 2020 - .03%

?? = เอกสาร Mozilla

|| = เอกสาร Mozilla

&& = เอกสารประกอบ Mozilla


เป็นความคิดที่ดีหรือไม่ที่จะคัดลอกคำตอบนี้ไปยังคำถามอื่นอีกสองคำถาม ( แทนที่ค่าถ้าเป็นโมฆะหรือไม่ได้กำหนดไว้ใน JavaScriptและมีตัวดำเนินการ“ null coalescing” ใน JavaScript หรือไม่ )? Voud จะดีกว่าถ้าทำซ้ำหรือเชื่อมโยงกับคำถามที่เกี่ยวข้องในความคิดเห็นหรือไม่
user4642212

คำถามต่างกันเล็กน้อย เช่นนี้เป็นคำตอบ ตัวอย่างมีความสอดคล้องเพื่อปรับปรุงบริบทแบบอินไลน์ได้อย่างรวดเร็ว อาจจะมีการเชื่อมโยงเพื่อดูรายละเอียดมากขึ้น แต่จะต้องมีการรำพิเศษที่อาจทำให้คนที่จะข้ามการแก้ปัญหา
Gibolt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.