`

JavaScript Garden - 该死的typeof 操作符

阅读更多

typeof 操作符

typeof 操作符(和 instanceof 一起)或许是 JavaScript 中最大的设计缺陷,
因为几乎不可能从它们那里得到想要的结果。

尽管 instanceof 还有一些极少数的应用场景,typeof 只有一个实际的应用(译者注这个实际应用是用来检测一个对象是否已经定义或者是否已经赋值),
而这个应用却不是用来检查对象的类型。

注意: 由于 typeof 也可以像函数的语法被调用,比如 typeof(obj),但这并是一个函数调用。
那两个小括号只是用来计算一个表达式的值,这个返回值会作为 typeof 操作符的一个操作数。
实际上不存在名为 typeof 的函数。

JavaScript 类型表格

Value               Class      Type
-------------------------------------
"foo"               String     string
new String("foo")   String     object
1.2                 Number     number
new Number(1.2)     Number     object
true                Boolean    boolean
new Boolean(true)   Boolean    object
new Date()          Date       object
new Error()         Error      object
[1,2,3]             Array      object
new Array(1, 2, 3)  Array      object
new Function("")    Function   function
/abc/g              RegExp     object (function in Nitro/V8)
new RegExp("meow")  RegExp     object (function in Nitro/V8)
{}                  Object     object
new Object()        Object     object

上面表格中,Type 一列表示 typeof 操作符的运算结果。可以看到,这个值在大多数情况下都返回 "object"。

Class 一列表示对象的内部属性 [[Class]] 的值。

JavaScript 标准文档中定义: [[Class]] 的值只可能是下面字符串中的一个:
ArgumentsArrayBooleanDateError
FunctionJSONMathNumberObjectRegExpString.

为了获取对象的 [[Class]],我们需要使用定义在 Object.prototype 上的方法 toString

对象的类定义

JavaScript 标准文档只给出了一种获取 [[Class]] 值的方法,那就是使用Object.prototype.toString

function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}

is('String', 'test'); // true
is('String', new String('test')); // true

上面例子中,Object.prototype.toString 方法被调用,this 被设置为了需要获取 [[Class]]值的对象。

译者注Object.prototype.toString 返回一种标准格式字符串,所以上例可以通过 slice截取指定位置的字符串,如下所示:

Object.prototype.toString.call([])  // "[object Array]"
Object.prototype.toString.call({})  // "[object Object]"
Object.prototype.toString.call(2)   // "[object Number]"

ES5 提示: 在 ECMAScript 5 中,为了方便,对 null 和 undefined 调用Object.prototype.toString 方法,
其返回值由 Object 变成了 Null 和 Undefined

译者注这种变化可以从 IE8 和 Firefox 4 中看出区别,如下所示:

// IE8
Object.prototype.toString.call(null)    // "[object Object]"
Object.prototype.toString.call(undefined)   // "[object Object]"

// Firefox 4
Object.prototype.toString.call(null)    // "[object Null]"
Object.prototype.toString.call(undefined)   // "[object Undefined]"

测试为定义变量

typeof foo !== 'undefined'

上面代码会检测 foo 是否已经定义;如果没有定义而直接使用会导致 ReferenceError 的异常。
这是 typeof 唯一有用的地方。

结论

为了检测一个对象的类型,强烈推荐使用 Object.prototype.toString 方法;
因为这是唯一一个可依赖的方式。正如上面表格所示,typeof 的一些返回值在标准文档中并未定义,
因此不同的引擎实现可能不同。

除非为了检测一个变量是否已经定义,我们应尽量避免使用 typeof 操作符。

 

2
1
分享到:
评论

相关推荐

    前端开源库-lutils-typeof.zip

    JavaScript中的`typeof`操作符虽然提供了基础的类型检测,但在某些复杂场景下,它并不能满足我们的需求。这时,开源库lutils-typeof应运而生,为开发者提供了更强大的类型检测功能。本文将详细探讨lutils-typeof库的...

    前端开源库-lutils-typeof

    这个库的核心功能是弥补JavaScript内置`typeof`操作符的一些不足,使得开发者能够更加精确地判断变量的类型。 JavaScript是一种动态类型语言,这意味着变量在运行时可以存储不同类型的数据,这在某些情况下可能会...

    前端开源库-drop-babel-typeof

    "drop-babel-typeof" 是一个特定于JavaScript的开源库,旨在优化编译过程,提升代码性能。这个库主要关注的是如何在不使用Symbol类型的条件下,去除Babel编译时产生的`typeof`检查所带来的冗余括号。 Babel是一个...

    JavaScript中的typeof操作符用法实例

    对一个值使用typeof操作符可能返回下列某个字符串:“undefined”——如果这个值未定义“boolean”——如果这个值是布尔值“string”——如果这个值是字符串“number”——如果这个值是数值“object”——如果这个是...

    javascript中typeof操作符和constucor属性检测

    在JavaScript中,typeof操作符和constructor属性是两种检测数据类型的方法。它们各自有不同的使用场景和特点。下面详细介绍这两者的知识内容。 首先,typeof操作符用于检测变量的数据类型。它对不同类型的变量会...

    JS中typeof与instanceof之间的区别总结.docx

    在JavaScript中,`typeof`和`instanceof`是两种常用的类型检查操作符,它们各自有着不同的用法和特点。理解这两者之间的差异对于编写健壮的JavaScript代码至关重要。 `typeof`操作符主要用于检测变量的数据类型。它...

    JavaScript_Garden_CN

    4. **类型**: 探讨了相等与比较、`typeof`操作符、`instanceof`操作符、类型转换等,这些都是处理数据类型时必须理解的概念。 5. **核心概念**: 强调了避免使用`eval`的重要性,解释了`undefined`和`null`的区别,...

    fj-typeof:FP-style typeof

    fj-typeof FP-style typeof 安装 npm install fj-typeof --save 用法 var typeOf = require ( 'fj-typeof' ) ; typeOf ( 'function' , typeOf ) ; // => true typeOf ( 'string' ) ( 'foo' ) ; // => true typeOf...

    一个月悟透javascript

    - **typeof操作符**: 用于检测变量的数据类型,返回一个表示该类型名称的字符串。 - `typeof undefined` 返回 "undefined"。 - `typeof null` 返回 "object"(这是JavaScript的一个特殊之处,实际上`null`被视为一...

    前端大厂最新面试题-typeof_instanceof.docx

    一、typeof 操作符 typeof 操作符返回一个字符串,表示未经计算的操作数的类型。使用方法如下:typeof operand 或 typeof(operand),其中 operand 表示对象或原始值的表达式,其类型将被返回。 例如: * typeof 1...

    jsjavascript基础教程.zip

    【教程简介】 ...03-数据类型和typeof操作符.md 04-运算符.md 05-条件判断语句.md 06-循环语句.md 07-数据类型转换基础.md 08-对象.md 09-函数_方法_枚举.md 10-作用域.md 11-工厂方法_构造函数_this关键字.md

    javascript之typeof、instanceof操作符使用探讨

    在JavaScript中,`typeof`和`instanceof`是两种常用的操作符,用于检查变量或对象的类型。然而,由于JavaScript的动态类型特性,这两个操作符的使用并不总能提供开发者期望的结果,有时甚至可能导致混淆。 `typeof`...

    javascript instanceof,typeof的区别

    在 JavaScript 中,instanceof 和 typeof 是两个常用的操作符,用于判断变量的类型和实例关系。然而,许多开发者对这两个操作符的区别和使用场景不够清楚,导致在编程中出现错误。下面,我们将详细介绍 instanceof ...

    javascript 教程-学习笔记.docx

    字符串是 JavaScript 中非常重要的数据类型之一,用于存储和操作文本数据。字符串可以使用单引号或双引号创建。 - **单引号**:`var str = 'Hello';` - **双引号**:`var str = "Hello";` 字符串中还可以包含转义...

    js代码-typeof的用法

    在JavaScript中,`typeof`操作符是一个非常关键的工具,用于确定变量或表达式的类型。它返回一个字符串,表示变量或表达式所对应的值的数据类型。`typeof`的使用不仅有助于防止类型错误,还能帮助我们在编写动态类型...

    javascript 操作符(~、&、-、^、<<、>>)使用案例.docx

    ### JavaScript 操作符详解 #### 一、按位非(~) 按位非操作符 `~` 是一个一元操作符,用于对一个整数进行按位取反操作。该操作符将每个二进制位从 `0` 变为 `1` 或从 `1` 变为 `0`。 **示例代码**: ```...

    js代码-实现new操作符

    在JavaScript中,`new`操作符是一个至关重要的概念,它用于创建对象实例并执行构造函数。这个过程涉及到了原型链、实例化以及上下文绑定等多个关键知识点。下面将详细讲解`new`操作符的工作原理以及如何用JavaScript...

    在JavaScript中typeof的用途介绍

    在JavaScript编程语言中,typeof是一个运算符,用于检测变量的数据类型。它能够返回一个表示变量类型的字符串值。尽管typeof在使用过程中非常直观,但它也有一些不太为人所知的特性,以及一些在历史上被认为是错误的...

Global site tag (gtag.js) - Google Analytics