最新要闻
- 武则天《升仙太子碑》 行草入碑敢为人先
- 中国特供显卡炒到20多万 英伟达赚麻了:有公司抢购70亿元订单-即时焦点
- 全球热头条丨大学期末划重点堪比发布会现场 学生举手机拍照 网友:很真实
- 科幻神作!三部《阿凡达》续集宣布推迟上映:第3部定档2025年
- 观天下!1152MB三级缓存天下无敌!AMD正式发布EPYC 9084X:96核心Zen4
- 突然!漫威多部新片宣布延期:《复仇者联盟5》《复仇者联盟6》再跳票1年_每日时讯
- 6月13日基金净值:信澳鑫安债券(LOF)最新净值1.009,跌0.1%
- 全球热点评!26岁零70天 Uzi成为LPL历史出场最年长的ADC选手
- 日本试运行核污染水排海设备 放射性物质将蔓延至全球海域
- 一男子挤痘后流血近1个小时 整个过程花费400抽面巾
- 梅西直播被吐槽上热搜前排 画面仅有一分钟引发大量网友不满
- 国产动漫《斗罗大陆2》即将开播 新史莱克七怪徐三石PV公布
- 埃兹拉·米勒出席《闪电侠》好莱坞活动 为官司缠身后的首次公开露面
- 云南金平县迎来蝴蝶集中羽化期 漫天飞舞犹如纷飞的落叶
- 辽宁一男子拔倒刺导致手指发炎感染 诊断为化脓性肉芽肿并缝了6针
- 为应对严重的黄牛倒卖问题 宝可梦社宣布新卡组将采用预购制
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
再也不用担心变量类型错误!学会JS中如何轻松检查变量类型_世界快看
今天要分享的问题就是:如何在JS中检查一个变量的类型?
(资料图)
先上结论:如果判断的是基本数据类型或JavaScript内置对象,使用toString;如果要判断的是自定义类型,请使用instanceof。
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型和 引用类型两大类。
基本类型也称为简单类型,按值访问。引用类型也称为复杂类型,按址访问。JavaScript内置了一些引用类型,如图所示:
JavaScript的变量是松散类型。虽然这使得提供类型信息的方式更加灵活了,但也容易误用。
下面来分析常见的四种JavaScript类型检查方法:typeof
, instanceof
, constructor
, toString
。
typeof
typeof
是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。
它返回的结果用该类型的字符串(全小写字母)形式表示。返回值有7种取值:number
、boolean
、symbol
、string
、undefined
、object
和function
。
typeof 3; // number 有效typeof true; //boolean 有效typeof Symbol(); // symbol 有效typeof ""; // string 有效typeof undefined; //undefined 有效typeof null; //object 无效typeof [] ; //object 无效typeof new Function(); // function 有效typeof new Date(); //object 无效typeof new RegExp(); //object 无效
有些时候,typeof
操作符会返回一些令人迷惑但技术上却正确的值:
- 对于基本类型,除
null
以外,均可以返回正确的结果。 - 对于引用类型,除
function
以外,一律返回object
类型。 - 对于
null
,返回object
类型。这是一个知名的bug。由于影响范围越来越大,就没有修复了。 - 对于
function
函数,返回 function 类型。从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。
由上可以得出:typeof
对引用类型操作的返回值不是我们想要的结果。
instanceof
instanceof
是用来判断 A 是否为 B 的实例的。它的表达式为:A instanceof B
。
如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof
断规则是某个对象的原型链是否包含某个构造函数的prototype属性
。
let arr = [];arr instanceof Array; // truearr instanceof Object; // true
看看arr原型链简图:
arr的 __proto__
直接指向Array.prototype
,间接指向 Object.prototype
,所以按照 instanceof
的判断规则,[] 就是Array的实例,也是Object的实例。instanceof
返回值都是true
。
依此类推,RegExp
, Object
, Function
也会形成一条对应的原型链 。
/abc/ instanceof RegExp // true({}) instanceof Object // true(function(){}) instanceof Function // true
instanceof
是通过原型链来检查类型的,所以适用于任何"object"的类型检查。自定义的类型同样满足。
// 比如直接原型关系function Fruit(){ }(new Fruit) instanceof Fruit // true// 原型链上的间接原型function Apple(){}Apple.prototype = new Fruit(new Apple) instanceof Fruit // true
注意instanceof
对基本数据类型不起作用,因为基本数据类型没有原型链。
3 instanceof Number // falsetrue instanceof Boolean // false"abc" instanceof String // falsenull instanceof String // always falseundefined instanceof String // always false
但你可以这样:
new Number(3) instanceof Number // truenew Boolean(true) instanceof Boolean // truenew String("abc") instanceof String // true
但这时你已经知道数据类型了,类型检查已经没有意义了。
使用constructor属性
constructor
属性返回一个指向创建了该对象原型的函数引用。需要注意的是,该属性的值是那个函数本身。例如:
function Fruit(){}var a = new Fruita.constructor === Fruit // true
constructor不适合用来判断变量类型。
- 其一,它是一个属性,非常容易被伪造:
var a = new Fruita.constructor === Arraya.constructor === Fruit // false
- 其二,
constructor
指向的是最初创建当前对象的函数,是原型链最上层的那个方法:
function Apple(){}Apple.prototype = new Fruitfunction BadApple(){}BadApple.prototype = new Apple(new BadApple).constructor === Fruit // trueFruit.constructor === Function // true
与instanceof类似,constructor只能用于检测引用对象,对基本数据类型无能为力。
与instanceof不同的是,在访问基本数据类型的属性时,JavaScript会自动调用其构造函数来生成一个对象。例如:
(3).constructor === Number // truetrue.constructor === Boolean // true"abc".constructor === String // true// 相当于(new Number(3)).constructor === Number(new Boolean(true)).constructor === Boolean(new String("abc")).constructor === String
这种将一个值类型转换为对象引用类型的机制在其他语言中也存在,称为装箱
。
但在基本数据类型中,null
和undefined
调用constructor
会抛出TypeError异常。
null.constructor // TypeError!undefined.constructor // TypeError!
因为null
是JavaScript原型链的起点,undefined
是无效对象,都没有构造函数,也就不存在constructor
属性。
instanceof跨窗口问题
我们知道Javascript是运行在宿主环境下的,而每个宿主环境会提供一套ECMA标准的内置对象,以及宿主对象(如window, document),一个新的窗口即是一个新的宿主环境。 不同窗口下的内置对象是不同的实例,拥有不同的内存地址。
而instanceof
和constructor
都是通过比较两个Function是否相等来进行类型判断的。 此时显然会出问题,例如:
var iframe = document.createElement("iframe");var iWindow = iframe.contentWindow;document.body.appendChild(iframe);iWindow.Array === Array // false// 相当于iWindow.Array === window.Array // false
因此iWindow中的数组arr原型链上是没有window.Array的。请看:
iWindow.document.write("<script> var arr = [1, 2]</script>");iWindow.arr instanceof Array // falseiWindow.arr instanceof iWindow.Array // true
使用toString方法
使用toString
方法是最为可靠的类型检测手段,它会将当前对象类型转换为字符串并输出。
toString
属性定义在Object.prototype上,因而所有对象都拥有toString方法。但Array
, Date
等对象会重写从Object.prototype继承来的toString,所以最好用Object.prototype.toString来检测类型。
toString = Object.prototype.toString;toString.call(new Date); // [object Date]toString.call(new String);// [object String]toString.call(Math); // [object Math]toString.call(3); // [object Number]toString.call([]); // [object Array]toString.call({}); // [object Object]// Since JavaScript 1.8.5toString.call(undefined); // [object Undefined]toString.call(null); // [object Null]
采用toString
也不是完美的,它无法检测用户自定义类型。因为Object.prototype是不知道用户会创造什么类型的,它只能检测ECMA标准中的那些内置类型。
toString.call(new Fruit) // [object Object]
因为返回值是字符串,也避免了跨窗口问题。当然IE弹窗中还是有Bug,不必管它了。 现在多少人还在用IE?多少人还在用弹窗?
和Object.prototype.toString类似地,Function.prototype.toString也有类似功能,不过它的this只能是Function,其他类型(例如基本数据类型)都会抛出异常。
其他
有时Duck Typing的类型推断方式也非常可行,貌似已经成为了前端的惯例。比如jQuery是这样判断一个Window的:
isWindow: function(obj){ return obj && typeof obj === "object" && "setInterval" in obj;}
总结
typeof
只能检测基本数据类型,对于null
还有Bug;instanceof
适用于检测对象,它是基于原型链运作的;constructor
指向的是最初创建者,而且容易伪造,不适合做类型判断;toString
适用于ECMA内置JavaScript类型(包括基本数据类型和内置对象)的判断;- 引用类型检查都有跨窗口问题,比如instanceof和constructor。
总之,如果你要判断的是基本数据类型或JavaScript内置对象,使用toString; 如果要判断的是自定义类型,请使用instanceof。
关键词:
再也不用担心变量类型错误!学会JS中如何轻松检查变量类型_世界快看
武则天《升仙太子碑》 行草入碑敢为人先
中国特供显卡炒到20多万 英伟达赚麻了:有公司抢购70亿元订单-即时焦点
全球热头条丨大学期末划重点堪比发布会现场 学生举手机拍照 网友:很真实
科幻神作!三部《阿凡达》续集宣布推迟上映:第3部定档2025年
观天下!1152MB三级缓存天下无敌!AMD正式发布EPYC 9084X:96核心Zen4
突然!漫威多部新片宣布延期:《复仇者联盟5》《复仇者联盟6》再跳票1年_每日时讯
6月13日基金净值:信澳鑫安债券(LOF)最新净值1.009,跌0.1%
全球热点评!26岁零70天 Uzi成为LPL历史出场最年长的ADC选手
日本试运行核污染水排海设备 放射性物质将蔓延至全球海域
一男子挤痘后流血近1个小时 整个过程花费400抽面巾
梅西直播被吐槽上热搜前排 画面仅有一分钟引发大量网友不满
国产动漫《斗罗大陆2》即将开播 新史莱克七怪徐三石PV公布
埃兹拉·米勒出席《闪电侠》好莱坞活动 为官司缠身后的首次公开露面
云南金平县迎来蝴蝶集中羽化期 漫天飞舞犹如纷飞的落叶
辽宁一男子拔倒刺导致手指发炎感染 诊断为化脓性肉芽肿并缝了6针
为应对严重的黄牛倒卖问题 宝可梦社宣布新卡组将采用预购制
《碟中谍7》中国内地定档7月14日正式上映 汤姆·克鲁斯惊喜回归
海外最大论坛网站Reddit遭网友怒怼 或使第三方应用无法访问该服务
MySql的MVCC机制
.NET 使用ILPack组件将程序集保存成dll 世界球精选
蔚来全系降价3万!未必心甘情愿 但又无可奈何:被大众收购才是出路?
4990元起!雅迪冠能探索E10发布:2000W电机、极速62Km/h 最资讯
欠薪过亿!时隔两月 宝能汽车总部又被“堵门”_每日视讯
《守望2》新付费PVE让玩家不爽:暴雪你还有脸要钱呢? 热头条
李想:并没把国内友商放在眼里 理想的目标是干BBA
现代C++学习指南-方向篇|焦点速读
文心一言 VS 讯飞星火 VS chatgpt (40)-- 算法导论5.4 4题|天天快播
天天快资讯:澳科大领衔的研究团队开发出新型人工智能医疗诊断模型
M2 Ultra加持!苹果新款Mac Studio评测:5万元的恐怖生产力
当前速看:马斯克称人类已经是半机器人:大脑思维上传服务器可永生
世界热讯:Arm发布全新智能视觉参考设计 首次整合第三方IP核心
“上四休三”的老板后悔了 有员工选择混:这制度对国人不适合? 环球快消息
央行下调常备借贷便利利率
MySQL索引
OnceCell和OnceLock的介绍-每日时讯
公开反对电动汽车后:丰田低头了
云南金平迎来蝴蝶大爆发:近亿只集中羽化 犹如纷飞落叶-世界观焦点
支持电视端:爱奇艺白金会员年卡+京东PLUS会员年卡248元
世界观点:SK-II回应神仙水是否有核污染:符合国家标准
每日报道:12代及以上CPU性能更强了!Intel为Linux开发新调度补丁
张轩昊丨操作思路分享【6月13日】今日黄金原油操作建议,实盘交易干货分享!
焦点速看:用纯HTML,JS,CSS实现横向滚动标签页
CSS常用属性
腾势N7盲订破2万台 增换购用户55%来自BBA等豪华品牌
世界短讯!特斯拉充电标准一天内被四家公司接受 网友:马始皇?
学习Win12好榜样?国产OS系统deepin成立AI社区:未来更智能_世界热头条
69元 小米车载充电器特惠开售:100W快充 配有炫彩灯效 时讯
环球热讯:历史性变革 大众汽车计划进行数十年来最大规模重组
年仅52岁!知名男演员在睡梦中去世... 今日热讯
国内第四大运营商 中国广电终于支持携号转网:但只入不出
刚考完科目一就买车上路 男子:想提前预习科目二、科目三
还说5G没用?全国5G平均下行速率348Mbps 比4G快6倍
环球视讯!被动散热靠谱么?博主实测15英寸MacBook Air性能表现
【新要闻】蔚来号召员工为车主献血 称“伙伴们都在积极报名”
焦点速讯:洛阳老城区:拆违治乱顺民意
【快播报】Collections类源码初探
天天微资讯!2023油价调整窗口时间表一览
马斯克 一统海外充电江湖!
新增自动拍摄功能:尼康Z9获4.00版本固件更新
90后小伙中1000万大奖 淡定回应先去上个班:不着急领
看热讯:阵容强大!长城汽车17位高管集体入驻微博:吉利副总裁盛赞
史低价!小米米家无线洗地机2开启618预售:仅1799元-当前视点
视点:过山车行情后,建筑钢材市场行情或易涨难跌
今日精选:Koordinator 最佳实践系列:精细化 CPU 编排
天天观察:Android RIL&IMS源码分析
天天即时:5款超级好用的开发效率工具,建议收藏!
世界观点:记录--为什么推荐用svg而不用icon?
油价小幅下调 加一箱油将少花2元 全球最资讯
惠誉博华:48家银行未赎回二级资本债券,合计达364.8亿元
恒生指数收涨0.6% 恒生科技指数大涨重回4000点上方
中海达(300177)6月13日主力资金净买入525.51万元_天天通讯
PMR机械硬盘走到尽头了!西数/希捷正疯狂自救
6旬老人守株待兔式飞奔撞车碰瓷索赔 车主吓坏:监控还清白 环球精选
广东有多热?网友在广东买虾 还没到家就熟了 世界今日讯
美国再将31家中企列入“实体清单”!
2999元的国产显卡值不值得冲?实测3A大作给你答案
焦点信息:天津:“多卡合一”创新服务“城市小蜜蜂”
今日热文:线段树学习笔记
每日速看!尚医通-day10【微信扫码登录】(内附源码)
linux iptables安全技术与防火墙_快播报
收评:创业板指涨0.68%收获三连阳 半导体行业涨幅靠前
全球快报:小米卢伟冰:小米13 Ultra在意法西德及香港地区正式开售 销售超预期
首发预装鸿蒙OS 4.0!华为Mate60 Pro概念图出炉 全球热资讯
天天精选!NASA决定造访遍地黄金的“灵神星”:平均每位美国人能分300亿美元
美系硬派SUV福特探险者谍照曝光!外观内饰全面升级 预计将在年内首次亮相_今日热讯
今日热搜:8GB显卡卖到3199元 显存成本曝光:英伟达实在太赚了
视点!男生抠掉脸上痘痘流血近1小时:用了一包400张抽纸
每日报道:6月13日华鲁恒升尿素价格暂稳
焦点信息:市场监管总局:瞄准先进材料、人工智能等领域推动建立国家标准参考数据中心
烟台大学附属中学石明校区举行垃圾分类科普讲座|天天时快讯
速递!8GB内存笔记本卖到10499元起 苹果被批吃相难看:应该破发
货车高速上连续疯狂别车被撞停 官方:未造成伤亡、已找到肇事者|当前播报
天天热讯:马斯克相中的男人!14岁成SpaceX最年轻工程师、岗位年薪百万
环球即时看!小米平板6 Pro两个月使用心得:找不到短板的安卓板皇
Arm发布全新智能视觉参考设计 首次整合第三方IP核心
2023安洵杯 re复现
每天一道面试题:Spring的Bean生命周期
Axure RP教程_编程入门自学教程_菜鸟教程-免费教程分享_环球今日讯
环球今日报丨哥伦比亚4名空难获救儿童的母亲生前或遭家暴,孩子外公和父亲欲争夺抚养权