惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
Schneier on Security
Schneier on Security
B
Blog RSS Feed
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
A
About on SuperTechFans
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
The GitHub Blog
The GitHub Blog
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
V2EX - 技术
V2EX - 技术
N
Netflix TechBlog - Medium
F
Fortinet All Blogs
V
Visual Studio Blog
Martin Fowler
Martin Fowler
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - Franky
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
The Exploit Database - CXSecurity.com
F
Full Disclosure
Scott Helme
Scott Helme
H
Heimdal Security Blog
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
Cyberwarzone
Cyberwarzone
Application and Cybersecurity Blog
Application and Cybersecurity Blog
V
Vulnerabilities – Threatpost
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
WordPress大学
WordPress大学
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Troy Hunt's Blog
S
SegmentFault 最新的问题
Forbes - Security
Forbes - Security
Jina AI
Jina AI
S
Securelist
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
J
Java Code Geeks
AWS News Blog
AWS News Blog
N
News and Events Feed by Topic
博客园 - 三生石上(FineUI控件)
量子位

講評世界

My App Defaults 2023 读书的意义 そして、次の曲が始まるのです 从零开始的 RSSHub Docker 私有化部署指南 使用 Homebrew 安装 Typora 的 0.11.18 版本 使用 TypeScript 为 Vue 组件的 prop 标注类型 【译文】Grid 用于布局, Flexbox 用于组件 【译文】IndexedDB 为什么这么慢?如何更好的使用呢? Hello 2022 「他山之石」零贰 「他山之石」零壹 「言論」 零壹 给 icarus 主题增加所有文章的字数统计 hexo 无法在本地实时预览 JavaScript 立即调用的函数表达式(IIFE) 解决 nvm 无法在 arm 架构下安装 V15 以下的 node 版本 的问题 m1 芯片安装 nvm 提示 command not found Cookie?小饼干! 使用 RSS 在推荐算法中获取主动权
如何在 JavaScript 完美的确定一个数据的类型
Moeyua · 2021-11-03 · via 講評世界

JavaScript 中有三种方式来确定一个数据的类型:

  • typeof 运算符
  • instanceof 运算符
  • Object.prototype.toString() 方法
    这里就来简单梳理一下这三种方式的优劣,同时得出一个能够完美判断数据类型的方法。

typeof

typeof 很简单,下面是一个简单的例子:

let a = 'foo';
let b = 1;
let c = true;
typeof a    // "string"
typeof b    // "number"
typeof c    // "boolean"

使用 typeof 判断『原始类型』(数值、字符串、布尔值)时分别返回 numberstringboolean。『合成类型』(对象、数组、函数)分别返回 objectobjectfunction

let a = {foo = 'bar'};
let b = ['foo', 'bar'];
let c = function(foo) {
    return foo + 'bar'
}
typeof a    // "object"
typeof b    // "object"
typeof c    // "function"

而对于 undefinednull 这两种类型,typeof 能够正常判断 undefined,但是 typeof null 会返回 object

let a = undefined;
let b = null;

typeof a    // "undefined"
typeof b    // "object"

出现这种情况的原因时最初版的 JavaScript 并没有将 null 单独拿出来作为一个数据类型,只是作为 object 类型的一种,后来将 null 单独拿了出来,但是为了兼容以前的旧的代码,就没有改变 typeof null 的返回值。

可见 typeof 大部分情况下确实能够准确判断出数据类型,但是对于 Arraynull 就会失效。

instanceof

instanceof 运算符返回一个布尔值,表示对象是否为某个构造函数的实例。根据这一特点我们就能够使用该运算符判断数据类型。

let a = {foo = 'bar'};
let b = ['foo', 'bar'];
let c = function(){};

a instanceof Object     // true
b instanceof Array      // true
c instanceof Function   // true

如上面的代码所示,instanceof 能够区分对象的各种类型,但是需要注意的是,instanceof 只能判断对象类型,对于 numberstringbooleanundefinednull 这几种类型是无法判断的。

Object.prototype.toString()

Object.prototype.toString() 方法的作用是返回一个对象的字符串形式,默认情况下返回类型字符串。不同数据类型的 toString 方法返回如下

数据类型返回值
数字[object Number]
字符串[object String]
布尔值[object Boolean]
数组[object Array]
函数[object Function]
undefined[object Undefined]
null[object Null]
arguments 对象[object Arguments]
Error 对象[object Error]
Date 对象[object Date]
RegExp 对象[object RegExp]
其他对象[object Object]

那么基于这一特性,我们可以近乎完美的确定一个常见数据的类型:

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

type({});// "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"

需要注意的是,由于实例对象可能会改写 Object.prototype.toSring,所以我们直接使用 Object.prototype.toSring,使用函数的 Call 方法在任意值上调用这个方法。

在上面这个type函数的基础上,还可以加上专门判断某种类型数据的方法。

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

['Null',
 'Undefined',
 'Object',
 'Array',
 'String',
 'Number',
 'Boolean',
 'Function',
 'RegExp'
].forEach(function (t) {
  type['is' + t] = function (o) {
    return type(o) === t.toLowerCase();
  };
});

type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true