好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

typeof

typeof

typeof 操作符返回 一个 字符串,表示未经计算的操作数的类型。(MDN)@H_ 502 _7@

typeof 可以用来检测 一个 值的类型。@H_ 502 _7@

1. 表现

在 ES6 之前,typeof 在浏览器的表现是这样的:@H_ 502 _7@

类型 结果 Boolean “boolean” String “string” Number “Number” Function “function” undefined “undefined” null “object” 数组 “object” 任意对象 “object”

  typeof   ;   //  输出 :"number" 

 typeof   '嘎?'  ;   //  输出 :"string" 

 typeof   true  ;   //  输出 :"boolean" 

 typeof  undefined ;   //  输出 :"undefined" 

 var   fn1   =   function  (  )   {  }  ; 
 function   fn2  (  )   {  }  ; 
 typeof  fn1 ;   //  输出 :"function" 
 typeof  fn2 ;   //  输出 :"function" 

 typeof   null  ;   //  输出 :"object" 

 typeof   [  ]  ;   //  输出 :"object"; 
 typeof   [  '9'  ,   '9'  ,   '6'  ]  ;   //  输出 :"object"; 

 typeof   {  }  ;   //  输出 :"object" 
 

2. 为什么检查 null 的类型返回 object

这是 一个 历史遗留问题,JavaScript 从出现开始都是这个表现。@H_ 502 _7@

  typeof   null  ;   //  输出 :"object" 
 

原因是 null 表示为 一个 空指针,其内部表示类型的 标签 和对象相同,所以会被设别为 object 。@H_ 502 _7@

有提案表示想要修复这个问题,使表现如下:@H_ 502 _7@

  typeof   null  ;   //  输出 :"null" 
 

但这个提案被拒绝了。@H_ 502 _7@

3. 为什么检查数组类型返回 object

数组的本质是个对象,从数组的原型上观察就可以发现。@H_ 502 _7@

@H_ 502 _7@@H_ 502 _7@

同时可以通过 instanceof 检测数组的原型链上是否有 Object。@H_ 502 _7@

 Array  instanceof   Object  ;   //  输出 :true 
 

4. 由基础对象构建的值也返回 object

事实上 typeof 只对字面量敏感。@H_ 502 _7@

  var  num  =   ; 

 typeof  num ;   //  输出 :"number" 
 

如果采用构造 函数 的形式得到 一个 值:@H_ 502 _7@

  var  num  =   new   Number  (  )  ; 

 typeof  num ;   //  输出 :"object" 
 

所以除了 Function ,构造出来的 一个 值,使用 typeof 检测类型都会返回 object 。@H_ 502 _7@

  var  fn  =   new   Function  (  'console.log("我是特例!")'  )  ; 

 typeof  fn ;   //  输出 :"function" 
 

5. 更精准的检测类型

使用 Object.prototype.toString.call ,可以更精准的检测类型。@H_ 502 _7@

 Object . prototype . toString .  call  (  )  ;   //  输出 : [object Number] 
Object . prototype . toString .  call  (  false  )  ;   //  输出 : [object Boolean] 
Object . prototype . toString .  call  (  null  )  ;   //  输出 : [object Null] 
Object . prototype . toString .  call  (  [  ]  )  ;   //  输出 : [object Array] 
Object . prototype . toString .  call  (  {  }  )  ;   //  输出 : [object Object] 
 

通过观察结果可以看到,使用这个方式可以区别出数组、对象、null这些 typeof 无法区分的类型。@H_ 502 _7@

可是为什么要这样用呢?不能直接 调用 一个 值的 toString 吗?@H_ 502 _7@

这涉及到了原型的问题,例如 Number :@H_ 502 _7@

  var  number  =   ; 

console .  log  ( number . __proto__ . toString )  ; 
 

number 变量的 toString 方法 其实就是 Number 的 prototype 属性 下的 toString 方法 。@H_ 502 _7@

  var  number  =   ; 

console .  log  ( number . __proto__ . toString  ===  Number . prototype . toString )  ; 
 

从这就可以看出进行 number.toString() 操作, 调用 的就不是 Object.prototype.toString 了。@H_ 502 _7@

这两个 toString 方法 的 内容 不同, Number.prototype.toString 做的事情其实就是根据一些规则,将值转成字符串,而 Object.prototype.toString 是将对象的 一个 类型 标签 进行组合 输出 。@H_ 502 _7@

也就是说大部分数据类型的原始对象都提供了新的 toString 方法 ,也就无法 调用 到 Object.prototype.toString ,所以要用这种方式。@H_ 502 _7@

那为什么 Object.prototype.toString 会可以精准判断出 一个 值的类型呢?@H_ 502 _7@

这是因为每个值都有 一个 对应的类型 标签 ,在标准中为 [[class]] 。@H_ 502 _7@

在 ES6 中,则是使用 Symbol.toStringTag 作为 标记 。@H_ 502 _7@

Object.prototype.toString 在 调用 的时候,就会访问这个 标记 ,并返回 [object 标记 ] 。@H_ 502 _7@

  var  obj  =   { 
   [ Symbol . toStringTag ]  :   '996'  , 
 }  ; 

Object . prototype . toString .  call  ( obj )  ;   //  输出 :"[object 996]" 
 

所有内置的类型都具有这个 标记 ,所以使用 Object.prototype.toString.call(值) 的方式可以更精准的 获取 到值的类型。@H_ 502 _7@

一些旧的数据类型的基础对象为了兼容性,可能访问不到 Symbol.toStringTag 接口,但是其他许多内置对象可以,例如 JSON 、 Math 、 BigInt 等:@H_ 502 _7@

 JSON [ Symbol . toStringTag ]  ;   //  输出 :"JSON" 
Math [ Symbol . toStringTag ]  ;   //  输出 :"Math" 
BigInt . prototype [ Symbol . toStringTag ]  ;   //  输出 :"BigInt" 
 

6. 小结

typeof 经常被用来检测基础类型,但是不够准确,无法区分数组、对象、null,更精准的检测应考虑使用 Object.prototype.toString 方法 。@H_ 502 _7@

delete 操作符 ? ?void

查看更多关于typeof的详细内容...

  阅读:36次

上一篇

下一篇

第1节:什么是 JavaScript    第2节:学习环境准备    第3节:调试方案    第4节:JavaScript 变量    第5节:JavaScript 数据类型    第6节:JavaScript if 语句    第7节:for 语句    第8节:JavaScript 算数运算符    第9节:JavaScript 比较运算符    第10节:JavaScript 逻辑运算符    第11节:JavaScript 函数    第12节:JavaScript 表达式    第13节:JavaScript 对象    第14节:JavaScript 字符串    第15节:JavaScript 数字    第16节:JavaScript 数组    第17节:JavaScript switch 语句    第18节:JavaScript while 语句    第19节:JavaScript 的 break 与 continue    第20节:JavaScript with    第21节:document.cookie    第22节:JavaScript Function    第23节:JavaScript Math    第24节:JavaScript Date    第25节:JavaScript RegExp    第26节:JavaScript JSON    第27节:什么是 DOM    第28节:DOM 和 JavaScript 的关系    第29节:获取和操作 DOM 节点    第30节:DOM 与事件    第31节:DOM 事件绑定    第32节:DOM 事件对象    第33节:DOM 事件流    第34节:事件相关的优化    第35节:自定义事件    第36节:表单校验    第37节:什么是 BOM    第38节:常用的 BOM 相关对象    第39节:BOM 常用属性和方法    第40节:AJAX    第41节:异常处理    第42节:三元运算符    第43节:逗号操作符    第44节:void    第45节:typeof    第46节:delete 操作符    第47节:debugger    第48节:getter & setter    第49节:new 运算符与构造函数    第50节:JavaScript 原型    第51节:JavaScript instanceof    第52节:JavaScript this    第53节:严格模式    第54节:作用域    第55节:闭包    第56节:变量提升    第57节:对象包装器    第58节:Lodash    第59节:moment    第60节:swiper    第61节:ECMAScript 6    第62节:Node.js    第63节:Babel    第64节:CSS 预处理器    第65节:代码规范    第66节:TypeScript    第67节:WebComponents    第68节:Vue、React、Angular    第69节:小程序    第70节:JavaScript 关键字    第71节:分号导致的问题    第72节:对象属性访问问题    第73节:this 使用问题    第74节:浮点数精度问题    第75节:独一无二的 NaN    第76节:避免全局污染    第77节:控制台观察对象问题    第78节:根据环境选择语言特性    第79节:相关资源