我一直保持使用檢查值是否未定義的做法
if (typeof x === 'undefined')
但是,一位同事建議使用if (x) {更好。
從計算的角度來看,這兩種方法有什么區別嗎?
uj5u.com熱心網友回復:
我想到的至少有兩個不同之處:
- 將型別檢查為未定義只檢查未定義,不像
if(x),檢查任何真值(例如true,非空字串,非零數字等) typeof即使在嚴格模式下,您也可以對不存在的變數執行操作。如果您從未宣告過x并且確實做過,您將收到參考錯誤if(x)
"use strict";
const a = undefined;
const b = "truthy value";
if(a) {
console.log("a in if"); // never executes
}
if(typeof a !== "undefined") {
console.log("a with typeof"); // never executes
}
if(b) {
console.log("b in if"); // executes
}
if(typeof b === "undefined") {
console.log("b with typeof"); // never executes
}
try {
if(c) console.log("this should error");
} catch(e) {
console.log("Can't access non-existent variable");
}
console.log("No error:", typeof c);
我什么時候應該使用哪一個?
一般:
使用if(x)時...
- 您正在檢查布林值
- 您正在檢查(不是)
0 - 您正在檢查一個非空的空字串(可能
if(string.length)改用) - 檢查函式的回傳值(例如,
null當沒有查詢結果時回傳函式,或者當有結果時回傳物件(DOM 函式類似于document.getElementById當不存在具有該 ID 的元素時回傳 null))
使用if(typeof x !== "undefined")時...
- 您正在檢查物件鍵是否存在 (
if(typeof obj.key !== "undefined")) (評論員指出的正確方法是 withObject.hasOwn(obj, "key")) - 您正在檢查變數是否存在(但不確定何時或為何這樣做)
- 檢查引數是否已傳遞
- 其他用途,例如撰寫 Express 服務器和檢查用戶提供的內容時
- 其他我可能忘記了......
uj5u.com熱心網友回復:
需要牢記的一點是,Javascript 是動態型別的,即使它看起來只是變數。JS 中有幾種型別,Undefined(帶大寫)是一種,它唯一可以容納的值是undefined. 把它想象成你有 Number 型別,它只接受 42。知道這一點很重要,因為 JS 引擎必須遵守規范。
Undefined 型別只有一個值,稱為 undefined。任何未賦值的變數都具有值 undefined。
應用程式代碼有很多變化,但您可以知道未分配的變數是具有值的未定義型別,undefined而不是其他型別。Undefined 旁邊是 Null,它只有一個值null. Null 與 Undefined 不同,需要賦值。
在規范中,您還將找到針對每種變數型別獲得的結果的表格。
你會注意到 Undefined 有它自己的回傳值,和 Boolean 一樣,但是Null 回傳"object",據報道這是我們無法擺脫的原始規范中的一個錯誤。
有了型別,我們就可以進行布爾強制轉換,這就是 if 陳述句如何計算條件的。該規范有一個案例表,定義了何時應將值強制轉換為trueor false。
您會看到一個if子句接收 Undefined 型別,它回傳false. Null 也會發生同樣的情況。還有一些其他情況也可以回傳 false,即使它們不是 Undefined 或 Null。
- 數值型別為
0,-0,NaN - 長度為 0 的字串型別 (
"") - 值為 0 的 BigInt 型別
正如其他人已經回答的那樣,規范的應用程式有幾個不同的地方。至于為什么typeof存在并且與錯誤評估有重疊的原因來自 JS 引擎如何處理值并將其強制轉換為布林值。
uj5u.com熱心網友回復:
if就像其他帖子建議的那樣檢查Truthy ,但這實際上取決于您所處的環境,在大多數情況下,這兩種方法都可以達到相同的目的。但當:
typeof(undefined) === undefined /* true */
typeof(0) === undefined /* false */
typeof(null) === undefined /* false */
if(!undefined)console.log(true); /* true */
if(!0)console.log(true); /* true */
if(!null)console.log(true); /* true */
在上面的示例中,您可以看到您的方法嚴格驗證undefined或檢查變數是否從未被賦值,并且if條件將忽略賦值0和null值。
如果您只想驗證 assigned-yet 或undefined值,那么您的同事顯然是錯誤的。
型別比較可能非常棘手和危險。根據我多年的編程經驗,我非常想建議:盡可能使用字串比較,我的意思是:
let a = new Array()
a.constructor.name === 'Array';
// is better than
typeof(a) === 'Array' /* false */
// and is better than
a instanceof Array
第二種方法可能適用于某些泛型型別,但對于自定義定義的類,typeof將始終回傳object.
該instanceof方法很危險,我不建議這樣做,尤其是當您處理跨站點通信時,window.postMessage或者在 . 上iframe,如果您window的腳本中有兩個物件,那么這兩個泛型型別是不同的。我的意思是:
let iframe = document.createElement('iframe');
document.body.appendChild(iframe);
let iwindow = iframe.contentWindow;
let idoc = iframe.contentDocument;
idoc.body.innerHTML = '<p>'
let ar = [1, 2, 3];
console.log(ar instanceof Array); // true
console.log(ar instanceof iwindow.Array); // false
// if you have an Array variable a in iframe, and a instanceof outer scope Array will return false too
有趣嗎?它們都是Array類,但不知何故回傳不同的比較結果。
所以,我完全同意你的方法,它是最嚴格的,出錯的可能性最小。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/535475.html
標籤:javascript
