jQuery本身不提供`typeof`與`with`,它們是**JavaScript核心語言特性**。本文釐清兩者用法、嚴重缺陷及現代最佳實踐。
typeof 操作符
語法與返回值
typeof operand
typeof (operand) // 函數式寫法,結果相同
| 運算元類型 | 返回字符串 |
| Undefined | `"undefined"` |
| Null | `"object"` (語言歷史BUG) |
| Boolean | `"boolean"` |
| Number | `"number"` |
| String | `"string"` |
| Symbol (ES6) | `"symbol"` |
| BigInt (ES2020) | `"bigint"` |
| Function | `"function"` |
| Object / Array / Date / RegExp / 等 | `"object"` |
常見用途
- 檢查變量是否聲明:`typeof x === "undefined"` (不拋ReferenceError)。
- 區分函數與對象:`typeof fn === "function"`。
- 類型守衛:`if (typeof val === "string")`。
局限性
- 無法區分`null`、數組、日期、正則等(均返回`"object"`)。
- 需配合`Array.isArray()`、`val instanceof Date`、`Object.prototype.toString.call(val)`精確判斷。
with 語句(嚴格模式禁用、強烈不推薦)
語法
with (object) {
// 語句塊內標識符優先解析為 object 屬性
property = value; // 相當於 object.property = value
}
致命缺陷
- 語義模糊:無法靜態確定標識符指向對象屬性還是外層變量,導致誤賦值、難以優化。
- 性能殺手:引擎無法優化作用域鏈查找。
- 嚴格模式下語法錯誤:`'use strict'; with(...) {}` → `SyntaxError`。
- 安全風險:惡意對象注入屬性竊取外層變量。
歷史用途(現已無需)
// 過去用於簡化深層對象訪問
with (document.forms[0].elements) {
name.value = "John";
email.value = "john@example.com";
}
// 現代寫法
const form = document.forms[0];
form.name.value = "John";
form.email.value = "john@example.com";
// 或解構賦值
const {name, email} = form.elements;
現代最佳實踐總結
| 需求 | 推薦方案 |
| 類型檢查 | `typeof` 基礎類型 + `Array.isArray()` + `instanceof` + `Object.prototype.toString.call()` |
| 簡化對象訪問 | 解構賦值、臨時變量引用、可選鏈 `?.` (ES2020) |
| 代碼塊作用域 | `{}` 塊級作用域 + `const`/`let` |
結論:善用 `typeof` 做基礎類型守衛,徹底拋棄 `with`,擁抱解構、可選鏈、嚴格模式。