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() 是否已經被聲明這樣的需求,可能沒那麼必要有自己的運算子。
不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

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

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

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

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

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

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

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

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具