แทนที่ค่าถ้าว่างหรือไม่ได้กำหนดใน JavaScript


128

ฉันมีความต้องการที่จะใช้ตัวดำเนินการ??C # กับ JavaScript และฉันไม่รู้วิธี พิจารณาสิ่งนี้ใน C #:

int i?=null;
int j=i ?? 10;//j is now 10

ตอนนี้ฉันตั้งค่านี้ใน JavaScript:

var options={
       filters:{
          firstName:'abc'
       } 
    };
var filter=options.filters[0]||'';//should get 'abc' here, it doesn't happen
var filter2=options.filters[1]||'';//should get empty string here, because there is only one filter

ฉันจะทำอย่างไรให้ถูกต้อง?

ขอบคุณ

แก้ไข: ฉันพบปัญหาครึ่งหนึ่ง: ฉันไม่สามารถใช้สัญกรณ์ 'ตัวทำดัชนี' กับวัตถุ ( my_object[0]) ได้ มีทางเลี่ยงไหม (ฉันไม่ทราบชื่อคุณสมบัติของตัวกรองล่วงหน้าและไม่ต้องการย้ำซ้ำ)

คำตอบ:


271

นี่คือสิ่งที่เทียบเท่ากับ JavaScript:

var i = null;
var j = i || 10; //j is now 10

โปรดสังเกตว่าตัวดำเนินการทางตรรกะ||ไม่ส่งคืนค่าบูลีน แต่เป็นค่าแรกที่สามารถแปลงเป็นจริงได้ได้

นอกจากนี้ยังใช้อาร์เรย์ของวัตถุแทนวัตถุเดียว:

var options = {
    filters: [
        {
            name: 'firstName',
            value: 'abc'
        }
    ]
};
var filter  = options.filters[0] || '';  // is {name:'firstName', value:'abc'}
var filter2 = options.filters[1] || '';  // is ''

ที่สามารถเข้าถึงได้โดยดัชนี


57
โปรดทราบว่าจะใช้ไม่ได้ถ้า 0 เป็นค่า i ที่ถูกต้อง
jt000

13
หากสิ่งใดที่เป็นเท็จเป็นอินพุตที่ถูกต้อง ( 0,, falseสตริงว่าง) ฉันจะทำสิ่งนี้แทนvar j = (i === null) ? 10 : i;ซึ่งจะแทนที่เท่านั้นnullแทนที่จะเป็นสิ่งที่สามารถประเมินเป็นเท็จได้
DBS

มีสิ่งนี้เทียบเท่ากับ Groovy หรือไม่?
user6123723

หากiไม่ได้กำหนดจะทำให้เกิดข้อผิดพลาด ดูเหมือนไม่มีประโยชน์สำหรับฉันดังนั้น .. (?)
phil294

@ phil294 var j = (i != null ? i : 10);ควรจะทำงานเพราะundefinedเป็น==โมฆะเพื่อให้i != nullเป็นfalseสำหรับทั้งสองและnull undefined
ToolmakerSteve

6

ฉันพบปัญหาครึ่งหนึ่ง: ฉันไม่สามารถใช้สัญกรณ์ 'ตัวทำดัชนี' กับวัตถุ (my_object [0]) มีทางเลี่ยงไหม

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

var someVar = options.filters.firstName; //Returns 'abc'

หรือโดยการวนซ้ำโดยใช้for ... inลูป:

for(var p in options.filters) {
    var someVar = options.filters[p]; //Returns the property being iterated
}

1
@LinusGeffarth โปรดทราบว่าfor inJS loop นี้ใช้งานได้กับตัวอักษรของวัตถุเท่านั้น! ล้มเหลวอย่างน่าสังเวชในอาร์เรย์ JS (ให้ดัชนี) และ JS Maps (ให้undefined) หวังว่าคุณจะไม่ลืมเพราะเกรงว่าคุณจะต้องเจอกับความประหลาดใจในการแก้จุดบกพร่อง! xP
varun

4

ES2020 คำตอบ

ใหม่Nullish coalescing Operator, เป็นที่สุดที่มีอยู่ใน JavaScript แม้ว่าการสนับสนุนเบราว์เซอร์จะถูก จำกัด ตามข้อมูลจากcaniuse รองรับเพียง 48.34% ของเบราว์เซอร์เท่านั้น (ณ เดือนเมษายน 2020)

ตามเอกสารประกอบ

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

const options={
  filters:{
    firstName:'abc'
  } 
};
const filter = options.filters[0] ?? '';
const filter2 = options.filters[1] ?? '';

เพื่อให้มั่นใจว่าทั้งสองตัวแปรของคุณจะมีค่าทางเลือกของ''ถ้าfilters[0]หรือfilters[1]มีหรือnullundefined

ทำจะทราบว่าผู้ประกอบการ nullish coalescing ไม่กลับค่าเริ่มต้นสำหรับประเภทอื่น ๆ ของมูลค่า falsy เช่นและ0 ''หากคุณต้องการการบัญชีสำหรับค่า falsy ||ที่ทุกท่านควรจะใช้หรือผู้ประกอบการ


0

การกำหนดตรรกะเป็นโมฆะโซลูชัน 2020+

??=ผู้ประกอบการใหม่ในขณะนี้จะถูกเพิ่มลงในเบราว์เซอร์, ซึ่งเทียบเท่ากับvalue = value ?? defaultValue.

||= และ &&=กำลังจะมาถึงลิงก์ด้านล่าง

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

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

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" }

ตัวอย่างการทำงาน

function config(options) {
    options.duration ??= 100
    options.speed ??= 25
    return options
}

config({ duration: 555 })   // { duration: 555, speed: 25 }
config({})                  // { duration: 100, speed: 25 }
config({ duration: null })  // { duration: 100, speed: 25 }

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

?? = เอกสาร Mozilla

|| = เอกสาร Mozilla

&& = เอกสาร Mozilla


0

โซลูชันการทำลายล้าง

เนื้อหาของคำถามอาจมีการเปลี่ยนแปลงดังนั้นฉันจะพยายามตอบอย่างละเอียด

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

const options = {
    filters : {
        firstName : "abc"
    } 
}

const {filters: {firstName = "John", lastName = "Smith"}} = options

// firstName = "abc"
// lastName = "Smith"

หมายเหตุ: การใช้อักษรตัวพิมพ์ใหญ่มีความสำคัญ

หากทำงานกับอาร์เรย์นี่คือวิธีที่คุณทำ

ในกรณีนี้ชื่อจะถูกแยกออกจากแต่ละออบเจ็กต์ในอาร์เรย์และกำหนดนามแฝงของตัวเอง เนื่องจากอาจไม่มีการ= {}เพิ่มวัตถุ

const options = {
    filters: [{
        name: "abc",
        value: "lots"
    }]
}

const {filters:[{name : filter1 = "John"} = {}, {name : filter2 = "Smith"} = {}]} = options

// filter1 = "abc"
// filter2 = "Smith"

บทช่วยสอนโดยละเอียดเพิ่มเติม

รองรับเบราว์เซอร์ 92% กรกฎาคม 2020

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