Thay thế một giá trị nếu null hoặc không xác định trong JavaScript


128

Tôi có yêu cầu áp dụng ??toán tử C # cho JavaScript và tôi không biết làm thế nào. Hãy xem xét điều này trong C #:

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

Bây giờ tôi đã thiết lập điều này trong 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

Làm thế nào để làm điều đó một cách chính xác?

Cảm ơn.

CHỈNH SỬA: Tôi đã phát hiện ra một nửa vấn đề: Tôi không thể sử dụng ký hiệu 'indexer' cho các đối tượng ( my_object[0]). Có cách nào để vượt qua nó không? (Tôi không biết trước tên của các thuộc tính bộ lọc và không muốn lặp lại chúng).

Câu trả lời:


271

Đây là JavaScript tương đương:

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

Lưu ý rằng toán tử logic|| không trả về giá trị boolean mà là giá trị đầu tiên có thể được chuyển đổi thành true .

Ngoài ra, hãy sử dụng một mảng các đối tượng thay vì một đối tượng:

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

Điều đó có thể được truy cập bằng chỉ mục.


57
Lưu ý rằng điều này không hoạt động nếu 0 là giá trị hợp lệ của i.
jt000

13
Nếu bất kỳ điều gì falsey là một đầu vào hợp lệ tiềm năng ( 0,, falsechuỗi trống), tôi sẽ làm điều gì đó như thế này để thay thế: var j = (i === null) ? 10 : i;Điều này sẽ chỉ thay thế null, chứ không phải bất kỳ thứ gì có thể được đánh giá là sai.
DBS

Có tương đương cho điều này ở Groovy không?
user6123723 21/02/18

nếu ikhông được xác định, điều này sẽ tạo ra một lỗi. dường như vô ích với tôi như vậy .. (?)
phil294

@ phil294 var j = (i != null ? i : 10);nên hoạt động, bởi vì undefined==null, vì vậy i != nullfalsecho cả nullundefined.
ToolmakerSteve

6

Tôi đã phát hiện ra một nửa vấn đề: Tôi không thể sử dụng ký hiệu 'indexer' cho các đối tượng (my_object [0]). Có cách nào để vượt qua nó không?

Không; một đối tượng theo nghĩa đen, như tên của nó, là một đối tượng chứ không phải một mảng, vì vậy bạn không thể chỉ đơn giản truy xuất một thuộc tính dựa trên một chỉ mục, vì không có thứ tự cụ thể của các thuộc tính của chúng. Cách duy nhất để truy xuất giá trị của chúng là sử dụng tên cụ thể:

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

Hoặc bằng cách lặp lại chúng bằng for ... invòng lặp:

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

1
@LinusGeffarth Lưu ý rằng for invòng lặp JS vui nhộn này chỉ hoạt động trên các ký tự đối tượng! Nó thất bại thảm hại trên các mảng JS (cho chỉ mục) và Bản đồ JS (cho undefined). Hy vọng bạn không quên điều đó, kẻo bạn sẽ gặp bất ngờ khi gỡ lỗi! xP
varun

4

Câu trả lời ES2020

Mới Nullish coalescing điều hành, là cuối cùng có sẵn trên JavaScript, mặc dù hỗ trợ trình duyệt bị giới hạn. Theo dữ liệu từ caniuse , chỉ 48,34% trình duyệt được hỗ trợ (tính đến tháng 4 năm 2020).

Theo tài liệu,

Toán tử kết hợp nullish (??) là một toán tử logic trả về toán hạng bên phải của nó khi toán hạng bên trái của nó là null hoặc không xác định, và nếu không trả về toán hạng bên trái của nó.

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

Điều này sẽ đảm bảo rằng cả hai biến của bạn sẽ có giá trị dự phòng là ''if filters[0]hoặc filters[1]are null, or undefined.

Hãy lưu ý rằng toán tử liên kết nullish không trả về giá trị mặc định cho các loại giá trị sai khác như 0''. Nếu bạn muốn tính toán tất cả các giá trị sai, bạn nên sử dụng toán tử OR ||.


0

Phân công vô hiệu hợp lý, giải pháp 2020+

Một toán tử mới hiện đang được thêm vào trình duyệt ??=,. Điều này tương đương với value = value ?? defaultValue.

||=&&=cũng đang đến, các liên kết bên dưới.

Điều này kiểm tra xem bên trái là không xác định hoặc rỗng, đoản mạch nếu đã được xác định. Nếu không, phía bên trái được gán giá trị bên phải.

Ví dụ cơ bản

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

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

// Equivalent to
a = a ?? true

Ví dụ về đối tượng / mảng

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

Ví dụ chức năng

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 }

?? = Hỗ trợ trình duyệt Tháng 7 năm 2020 - 0,03%

?? = Tài liệu Mozilla

|| = Tài liệu Mozilla

&& = Tài liệu Mozilla


0

Giải pháp tái cấu trúc

Nội dung câu hỏi có thể đã thay đổi, vì vậy tôi sẽ cố gắng trả lời cặn kẽ.

Hủy cấu trúc cho phép bạn kéo các giá trị ra khỏi bất kỳ thứ gì có thuộc tính. Bạn cũng có thể xác định các giá trị mặc định khi null / undefined và đặt tên cho bí danh.

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

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

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

LƯU Ý: Vấn đề viết hoa

Nếu làm việc với một mảng, đây là cách bạn thực hiện.

Trong trường hợp này, tên được trích xuất từ ​​mỗi đối tượng trong mảng và có bí danh riêng. Vì đối tượng có thể không tồn tại = {}cũng đã được thêm vào.

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

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

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

Hướng dẫn chi tiết hơn

Hỗ trợ trình duyệt 92% tháng 7 năm 2020

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.