原生JS灵魂之问——你真的懂这些JS吗?
最近在看ES6(可能是初到公司的缘故,处于振奋与繁忙的事带来的无力之中。。。不过还是坚持认真阅读了《深入浅出ES6》,确实是本好书),里面一些内容会时不时让人有“恍然大悟”之感。
先说下 JS数据类型:
原始数据类型和引用数据类型
原始数据类型 (6种)
- boolean
- null
- undefined
- number
- string
- symbol
引用数据类型:
- 对象 object(包括object,Array,RegExp,Date,Math…)
- 函数 Function
这里的“null”是个对象吗?
我们 console.log(typeof null);
,会输出:object。但这只是JS存在已久的Bug,它不是对象。
但JS之初用的32位系统,为了性能考虑使用低位存储变量的类型信息,000开头代表是对象,然而null全0,所以,就将其判为object。
typeof能否正确判断类型?
我们知道,对于原始类型:除了null都可正确判断。
但对引用数据类型,除函数外,皆为object。
这样,采用typeof未免有些不合适。
我们想到了 instanceof——基于原型链的查询 。
var str='hello!';
str instanceof String // false
const Person=function(){}
const p1=new Person()
p1 instanceof Person // true
它当然也能判断基本数据类型:
class PrimitiveNum{static [Symbol.hasInstance](x){return typeof x==='number'}
}
console.log(111 instanceof PrimitiveNum) // true
其实,我们就是通过Symbol将原有的instanceof重新定义成了typeof,这是自定义instanceof行为的一种方式。
玩个刺激的,
手动实现instanceof
我想到了 基于原型链的向上查找
function myInstanceof(left,right){//基本数据类型直接返回falseif(typeof left !== 'object' || left === null) return false;//利用Object的自带方法拿到参数的原型对象let proto=Object.getPrototypeOf(left);while(true){if(proto==null) return false; //参数的原型可能为nullif(proto==right.prototype) return true;proto=Object.getPrototypeOf(proto); //若上面不符,取自己的“原型对象”,继续向下走}
}
测试一下:
console.log(myInstanceof("111",String)); // false
console.log(myInstanceof(new String("111"),String)); // true
有趣的是,《深入浅出ES6》也对此有一个示例:(ES5模拟默认参数,通过typeof检查参数类型)
function makeRequest(url,timeout,callback){timeout=(typeof timeout !== "undefined") ? timeout : 2000;callback=(typeof callback !== "undefined") ? callback : function(){};//其余实现
}
运用:instanceof左操作数是一个类,右操作数是标识对象的类,如果左侧对象是右侧类的实例,则返回true
所以,一般用typeof判断基本类型,其余的再用instanceof判断
Object.is和===
作为 ES6的新增方法 ,Object.is() 和 Object.assign() 在ES里掀起了“简洁便利之风”。
我们着重说下Object.is()方法:
《深入浅出ES6》中提到:当你想在JavaScript中比较两个值时,可能习惯于使用相等运算符(= = )或全等运算符( = = =),许多开发者更喜欢后者,从而避免在比较时触发强制类型转换的行为。
但是,全等运算符也不一定准确啊:
+0和-0在JavaScript引擎中被表示为两个完全不同的实体,而全等运算符却将其归为一类;
NaN===NaN的返回值应该为true,但在JavaScript中也需要使用isNaN()来表示。
ES6引入了Object.is()方法来弥补全等运算符的不准确运算:
console.log(+0 == -0); // true
console.log(+0 === -0); // false
console.log(Object.is(+0,-0)); // falseconsole.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN,NaN)); // trueconsole.log(5 == "5"); // true
console.log(5 === "5"); // false
console.log(Object.is(5,"5")); // false
0.1+0.2!==0.3?
不用怀疑,确实是这样。
内部原理是什么?
我们计算机的信息全部转化为二进制进行存储的,那么0.1的二进制表示的是一个无限循环小数,JS采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失,造成了0.1不再是0.1(实际偏大了一点)——截取后0.1变成了0.100…001,,02变成了0.200…002,所以相加后的数大于0.3
为什么0.3+0.4==0.5?
由上可知:计算机要对数据进行截取,以获取“合理”的值。从实际来看,0.3截取后的值加上0.4截取后的值恰好等于0.5截取后的值。。。
那为什么在控制台console.log(0.1),还等于0.1呢?
在输入内容进行转换的时候,二进制转换成十进制,然后又十进制转换成字符串,在这个转换的过程中发生了取近似值。所以打印出来的是一个近似值。
原生JS灵魂之问——你真的懂这些JS吗?相关推荐
- js 自动分配金额_(2.4w字,建议收藏)??原生JS灵魂之问(下), 冲刺??进阶最后一公里(附个人成长经验分享)
笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...
- 【亡羊补牢】JS灵魂之问 第23期 修炼内功 关于闭包的回顾
引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 闭包的回顾 ,那今天这篇看能不能问倒你了,一起来探索一下吧. 仰望星空的 ...
- 【亡羊补牢】JS灵魂之问 第19期 修炼内功 对象枚举知多少
引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 对象枚举 ,那今天这篇看能不能问倒你了,一起来探索一下吧. 仰望星空的人 ...
- 【亡羊补牢】JS灵魂之问 第18期 修炼内功 Object.creat()基础
引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 Object.creat()基础 ,那今天这篇看能不能问倒你了,一起来探 ...
- (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上)
笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...
- 原生JS灵魂之问(中),看看你是否熟悉JavaScript?
笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...
- 【面试利器】 原生JS灵魂拷问,你能答上多少(一)
前言 目前的前端世界,三大框架横行,原生JavaScript所用越来越少.但我认为JavaScript作为每一个前端工程师的立身之本,学再多遍都不为过. 因此我决定整理JavaScript中容易忽视或 ...
- 可以用于云原生中Skywalking框架原理你真的懂吗
可以用于云原生中Skywalking框架原理你真的懂吗 ✨博主介绍 全链路监控 什么是全链路监控,为什么我们需要全链路监控? OpenTracing OpenTracing定位 OpenTracing ...
- 前端要懂mysql_【灵魂拷问】你真的懂得Mysql的管理和使用吗?
作者 | Jeskson 来源 | 达达前端小酒馆 MySQL管理,数据库管理和数据表管理,用户管理. 初始化数据库,创建数据库,查看数据库,删除数据库. 创建数据表,查看数据表,修改数据表,删除数据 ...
最新文章
- mac 思科 链路聚合_TCP/IP协议栈-之-数据链路层分析
- 那个分分钟处理10亿节点图计算的Plato,现在怎么样了?
- CTO 写的代码,真是绝了
- python怎么打印出文件的内容,python怎么将打印输出日志文件
- svn 邮件通知及LOG处理 强制提交log日志
- DUILib 中的通知事件
- 鸿蒙适配倒计时,倒计时2天!首批鸿蒙OS适配名单确定,你的手机在列吗?
- CSS3 box flex 布局
- Inner Join, Left Outer Join和Association的区别
- hibernate 映射四多对一双向映射
- 三态输出门实验报告注意事项_数电基础知识:各种IO输出的类型
- 斯特林公式--求n!的位数
- centos7 挂载磁盘_Linux磁盘管理之LVM
- 第十五章:进程间通信
- 广东省惠州市谷歌卫星地图下载
- 通达信登录服务器文件夹,我也搞定了通达信交易系统多帐号登录交易!
- Pandas基础:列方向分组变形
- CSS数学函数- 阶梯值函数round() mode() rem()
- nssl 1467.U
- std::tr1::function
热门文章
- CE修改模拟器里的数据
- 震撼热聘: ZLG(周立功)集团诚聘软件工程师(多种职位!!!)
- 山西高平地域文化导入美术设计实训项目的实践
- 数据库面试题:对称加密和非对称加密的区别
- laypage 分页控件使用方法
- GitBook插件整理 - book.json配置
- 大概只有程序猿本猿才能看得懂的梗~
- vivoiqoo系统会加入鸿蒙吗,iqoo系统和vivo系统不一样 iqoo系统和vivo有什么区别 - 云骑士一键重装系统...
- LTG TWL 150/1064/N风机
- Redis | 跳跃表