JavaScript 的 typeof 的用途
JavaScript 中的 typeof 其實非常複雜,它可以用來做很多事情,但同時也有很多怪異的表現。 本文列舉出了它的多個用法,而且也指出了存在的問題以及解決方案。
閱讀本文的前提是,你現在應該已經知道原始值和物件值的差別了。
檢查一個變數是否存在,是否有值
typeof在兩種情況下會回傳"undefined":
變數沒有被宣告
: > typeof undeclaredVariable === "undefined"true > var declaredVariable; > typeof undefined'undefined'還有其他辦法偵測某個值是否為undefined: > var value = undefined;> value === undefinedtrue但如果使用這種方法在一個未宣告的變數上會拋出異常,因為只有typeof 才可以正常檢測未聲明的變數的同時還不報錯: > undeclaredVariable === undefinedReferenceError: undeclaredVariable undefinedReferenceError: undeclaredVariable undefinedReferenceError: undeclaredVariable isabled被傳入參數的形參,不存在的屬性,都不會出現上面的問題,因為它們總是可訪問的,值總是undefined: > var declaredVariable;> declaredVariable === undefined true > (function (x) { return x === undefined }())true :因此,如果想要偵測一個可能沒有被宣告的全域變數是否存在,也可以使用if(window.maybeUndeclaredVariable){}。 問題:typeof 在完成這樣的任務時顯得很繁雜. 解決辦法:這樣的操作不是很常見,所以有人覺的沒必要再找更好的解決辦法了。 不過也許有人會提出一個專門的操作符: > defined undeclaredVariablefalse > var deccariable;有人還需要一個檢測變數是否被陳述的操作符: > declared undeclaredVariablefalse > var declaredVariable;Voperal,上面的defined 運算子相當於defined( ),上面的declared 運算子相當於exists()。
判斷一個值不等於undefined 也不等於null
問題:如果你想檢測一個值是否被定義過(值不是undefined 也不是null),那麼你就遇到了typeof 最有名的一個怪異表現(被認為是一個bug):typeof null 回傳了"object":
> typeof null
'object'
譯者註:這只能說是最初的JavaScript 實現的bug,而現在標準就是這樣規範的。 V8 曾經修正並實現過 typeof null === "null",但最終證明不可行。 http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null。
(翻譯:typeof 在操作null 時會返回"object",這是JavaScript 語言本身的bug。不幸的是,這個bug 永遠不可能被修復了,因為太多已有的程式碼已經依賴了這樣的表現。方法:不要用typeof 來做這項任務,用下面這樣的函數來取代:
function isDefined(x) {
return x !== null && x !== undefine
return x !== null && x !== undefinereturn x !== null && x !== undefined;一個可能性是引入一個“預設值運算子”,在myValue 未定義的情況下,下面的表達式會返回defaultValue:
myValue ?? defaultValue
上面的表達式等價於:
(myValue !== undefined && myValue !== null) ? myValue : defaultValue又或: myValue ??= defaultValue ??defaultValue當你存取一個嵌套的屬性時,例如bar,你或許會需要這個運算子的幫助: obj.foo.bar如果objobj.foo 是未定義的,上面的表達式會拋出異常。 一個運算子.?? 可以讓上面的表達式在遍歷一層一層的屬性時,傳回第一個遇到的值為undefined 或null 的屬性: obj.??foo.??bar??foo.??bar?? 上面的表達式等價於: (obj === undefined || obj === null) ? obj
: (obj.foo === undefined || obj.foo === null) ? obj.foo
: obj.foo.bar
是否使用是物件值:
function isObject(x) {
return (typeof x === "function"
}問題:上面的偵測比較複雜,是因為typeof 把函數和物件看成是不同的類型,而且typeof null 回傳"object". 解決方法:下面的方法也常用於偵測物件值: function isObject2(x) { return x === Object(x);}警告:你也許認為這裡可以使用instance instance 來偵測的原型來判斷實例關係的,那麼沒有原型的物件怎麼辦呢: > var obj = Object.create(null);> Object.getPrototypeOf(obj)
> Object.getPrototypeOf(obj)
對象,但它不是任何值的實例: > typeof obj'object'> obj instanceof Objectfalse存在,而且有它的用途。 譯者註:Object.prototype 就是唯一的一個內建的,沒有原型的物件。 >Object.getPrototypeOf(Object.prototype)null>typeof Object.prototype'object'
typeof 是最好的用來查看某個原始值的類型的方式。
> typeof "abc"
'string'
> typeof undefined
'undefined'
問題:你必須知道 typeof null 的怪異表現。
> typeof null // 要小心!
'object'
解決方法:下面的函數可以修復這個問題(只針對這個用例)。
function getPrimitiveTypeName(x) {
var typeName = typeof x;
switch(typeName) { case "boolean":
case "number":
case " string":
return typeName;
case "object":
return "null";
}
default: // 前面的判斷皆未通過
throw new TypeError("參數不是原始值: "+x);
}
}
更好的解:實作一個函數getTypeName(),除了可以傳回原始值的的型別,還可以傳回物件值的內部[[Class]] 屬性。 這裡講如何實現這個函數(譯者註:jQuery 中的 $.type 就是這樣的實作)
某個值是否是函數
typeof 可以用來偵測一個值是否是函數。
> typeof function () {}
'function'
> typeof Object.prototype.toString
'function'instance
乍一看,似乎寫法更優雅。 但是,瀏覽器有一個怪癖:每個框架和視窗都有它自己的全域變數。 因此,如果你將某個框架中的物件傳到另一個框架中,instanceof 就無法正常運作了,因為這兩個框架有著不同的建構子。 這就是為什麼 ECMAScript5 中會有Array.isArray() 方法的原因。 如果有一個能夠跨框架的,用於檢查一個物件是否是給定的建構函數的實例的方法的話,那會很好。 上述的 getTypeName() 是一個可用的變通方法,但也許還有一個更根本的解。 綜述下面提到的,應該是目前 JavaScript 中最迫切需要的,可以代替一些typeof 目前職責的功能特性: isDefined() (比如Object.isDefined()): 可以作為一個函數或運算子 isObject() getTypeName() 是否已經被聲明這樣的需求,可能沒那麼必要有自己的運算子。
熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務
