javascript đặt một biến nếu không xác định


172

Tôi biết rằng tôi có thể kiểm tra biến javascript và sau đó xác định nó nếu nó không được xác định, nhưng không có cách nào để nói

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

có vẻ như là một cách rõ ràng hơn nhiều, và tôi khá chắc chắn rằng tôi đã thấy điều này trong các ngôn ngữ khác.


30
đó không phải là một thử nghiệm cho "không xác định", đó là một thử nghiệm cho "falsey"
Alnitak

3
Lưu ý rằng localStorage.getItem()sẽ ném một ngoại lệ nếu người dùng đã tắt cookie (ít nhất là trong Chrome), vì vậy bạn có thể muốn bọc nó trong một try...catchđiều khoản
thúc giục

Câu trả lời:


304

Vâng, nó có thể làm điều đó, nhưng nói đúng ra rằng sẽ gán giá trị mặc định nếu giá trị được truy xuất là falsey , trái ngược với thực sự không xác định . Nó sẽ do đó không chỉ phù hợp undefinedmà còn null, false, 0, NaN, "" (nhưng không "0" ).

Nếu bạn chỉ muốn đặt thành mặc định nếu biến đó là nghiêm ngặt undefinedthì cách an toàn nhất là viết:

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

Trên các trình duyệt mới hơn, nó thực sự an toàn để viết:

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

nhưng lưu ý rằng có thể lật đổ điều này trên các trình duyệt cũ hơn, nơi nó được phép khai báo một biến có tên undefinedcó giá trị xác định, khiến thử nghiệm thất bại.


3
Tôi ngạc nhiên khi mẫu này không được bao gồm trong nhiều lib lib hơn.
joemaller

Có một nhược điểm để sử dụng var x = (x === undefined ? def_val : x);như lâu hơn một chút var x = (typeof x === 'undefined') ? def_val : x;. Liệu hành vi khác nhau?
Marco Pashkov

3
@marco trong các trình duyệt cũ hơn có thể undefinedđược xác định lại, khiến cho bài kiểm tra đẳng thức không thành công.
Alnitak

@Alnitak cách tiếp cận tốt nhất để sử dụng cú pháp tương tự với cú pháp mà OP đang sử dụng và vẫn kiểm tra không xác định là gì?
Ivo Pereira

@IvoPereira Bạn không thể sử dụng ||phương pháp tiếp cận trong một bài kiểm tra nghiêm ngặt đối với không xác định, bạn phải sử dụng một bài kiểm tra rõ ràng undefinedvới một điều kiện.
Alnitak

26

Câu trả lời ES6 2018 là :

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

Nếu biến x không xác định, trả về biến y ... nếu không, nếu biến x được xác định, trả về biến x.


4
Theo như tôi có thể nói, Object.iskhông có gì tốt hơn ===trong trường hợp này. "Toán tử === (và cả toán tử ==) cũng coi các giá trị số -0 và +0 là bằng nhau và coi Number.NaN không bằng NaN." ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ mẹo ) Không quan trọng ở đây.
Trevor Dixon

5
Tôi không đồng ý. Biết cả hai và sử dụng một trong những thích hợp. Cụ thể, sử dụng Object.isnếu cả hai toán hạng có thể NaN.
Trevor Dixon

2
Nếu Object.is () hoạt động trên 100% các trường hợp sử dụng và === hoạt động trên 98% các trường hợp sử dụng, tại sao bạn lại có nguy cơ sử dụng ===? Ví dụ: console.log (+0 === -0); // xuất ra true, trong khi console.log (Object.is (+0, -0)); // đầu ra sai - cái nào tốt hơn? Là âm 0 giống như dương 0? Đó là câu hỏi bạn phải tự hỏi mình, nhưng nếu bạn sử dụng Object.is (), bạn luôn biết câu trả lời. Chúng không giống nhau, vì vậy một kết quả sai là kết quả chính xác và được mong đợi.
Sterling Bourne

2
Bối cảnh cụ thể ở đây luôn luôn so sánh với undefined. Vì vậy, ===sẽ làm việc 100% thời gian, không chỉ 98%. Ưu điểm của ===nó là dễ đọc hơn, đặc biệt là trong nháy mắt, ngắn hơn và tránh một cuộc gọi phương thức không cần thiết. Cá nhân tôi sẽ chỉ sử dụng Object.is()khi tình huống yêu cầu và thích ===trong tất cả các trường hợp khác.
blubberdiblub

1
Chắc chắn rồi; nếu bạn là một lập trình viên có kinh nghiệm Trừ khi bạn vô tình quên một dấu bằng, trong trường hợp đó, việc gỡ lỗi tại sao == không hoạt động ở đâu đó là điều tôi không bao giờ mong muốn đối với bất kỳ nhà phát triển nào. An toàn tốt hơn xin lỗi và luôn sử dụng Object.is (), lý do được bao gồm trong thông số cụ thể là để giúp các nhà phát triển viết mã lỗi ít hơn.
Sterling Bourne

7

Tôi cần phải "đặt một biến nếu không xác định" ở một số nơi. Tôi đã tạo một hàm bằng cách sử dụng câu trả lời @Alnitak. Hy vọng nó sẽ giúp được ai đó.

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

Sử dụng:

hasPoints = setDefaultVal(this.hasPoints, true);

6

Có vẻ hợp lý hơn để kiểm tra typeofthay vì undefined? Tôi giả sử bạn mong đợi một số khi bạn đặt var thành 0khi không xác định:

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

Trong trường hợp này nếu getVariablekhông phải là số (chuỗi, đối tượng, bất cứ thứ gì), setVariable được đặt thành0


5

Trả lời ES2020

Với Toán tử kết hợp Nullish , bạn có thể đặt giá trị mặc định nếu valuelà null hoặc không xác định.

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

Tuy nhiên, bạn nên lưu ý rằng toán tử kết hợp nullish không trả về giá trị mặc định cho các loại giá trị giả khác như 0''.

Xin lưu ý rằng hỗ trợ trình duyệt cho nhà điều hành bị hạn chế. Theo dữ liệu từ caniuse , chỉ có 48,34% trình duyệt được hỗ trợ (tính đến tháng 4 năm 2020). Hỗ trợ Node.js đã được thêm vào trong phiên bản 14 .


2

Nếu bạn là người hâm mộ của FP ( lập trình chức năng ), Ramda có chức năng trợ giúp gọn gàng cho cái gọi là defaultTo :

sử dụng:

const result = defaultTo(30)(value)

Nó hữu ích hơn khi xử lý undefinedcác giá trị boolean:

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


1
điều này là chính xác const result = value || 30;, ngoại trừ việc sử dụng hàm ở giữa và +1000 byte lib
Adelin

1
@Adelin không đúng, nó cũng xử lý sai cho các kiểu boolean. Nếu bạn đã sử dụng lib này (như tôi) thì nó khá hữu ích và tuyệt vời
Damian Green

1

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


Sẽ không được tính 0 nếu localStorage.getItem('value'))trả vềfalse
Karl Adler

1

Chạy vào kịch bản này ngày hôm nay cũng là nơi tôi không muốn số 0 bị ghi đè cho một số giá trị. Chúng tôi có một tệp với một số phương thức tiện ích phổ biến cho các tình huống như thế này. Đây là những gì tôi đã thêm để xử lý kịch bản và linh hoạt.

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

Sau đó, nó có thể được gọi với hai tham số cuối cùng là tùy chọn nếu tôi muốn chỉ đặt cho các giá trị không xác định hoặc ghi đè lên giá trị null hoặc 0. Đây là một ví dụ về một cuộc gọi đến nó sẽ đặt ID thành -1 nếu ID không xác định hoặc null, nhưng sẽ không ghi đè lên giá trị 0.

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

1

Trong thời đại của chúng tôi, bạn thực sự có thể thực hiện cách tiếp cận của mình với JS:

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

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

console.log(x); // default value

Vì vậy, ví dụ của bạn S work hoạt động:

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

0

Hoạt động ngay cả khi giá trị mặc định là giá trị boolean:

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

0

Dường như với tôi, đối với việc triển khai javascript hiện tại,

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

là một cách hay để làm điều này (sử dụng giải cấu trúc đối tượng).


0

Phân công logic nullish, giải pháp ES2020 +

Nhà khai thác mới hiện đang được bổ sung vào trình duyệt, ??=, ||=, và &&=. Bài này sẽ tập trung vào ??=.

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

Phương pháp so sánh

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

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

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

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ụ đố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" }

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

?? = Tài liệu Mozilla

|| = Tài liệu Mozilla

&& = Tài liệu Mozilla


Có thực sự là một ý tưởng tốt để sao chép câu trả lời này sang hai câu hỏi khác ( Thay thế một giá trị nếu null hoặc không xác định trong JavaScriptCó một toán tử null kết hợp lại toán tử trong JavaScript không? )? VTC có tốt hơn không khi trùng lặp hoặc liên kết đến các câu hỏi liên quan trong các bình luận?
dùng4642212

Các câu hỏi đều hơi khác nhau; như vậy là câu trả lời Các ví dụ phù hợp để cải thiện bối cảnh nội tuyến trong nháy mắt. Có lẽ có thể đã liên kết để biết thêm chi tiết, nhưng sẽ cần thêm một bước nhảy có thể khiến mọi người bỏ qua giải pháp
Gibolt
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.