最近在看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吗?相关推荐

  1. js 自动分配金额_(2.4w字,建议收藏)??原生JS灵魂之问(下), 冲刺??进阶最后一公里(附个人成长经验分享)

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...

  2. 【亡羊补牢】JS灵魂之问 第23期 修炼内功 关于闭包的回顾

    引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 闭包的回顾 ,那今天这篇看能不能问倒你了,一起来探索一下吧. 仰望星空的 ...

  3. 【亡羊补牢】JS灵魂之问 第19期 修炼内功 对象枚举知多少

    引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 对象枚举 ,那今天这篇看能不能问倒你了,一起来探索一下吧. 仰望星空的人 ...

  4. 【亡羊补牢】JS灵魂之问 第18期 修炼内功 Object.creat()基础

    引言 有几天没有更新JS灵魂之问的专栏系列文章了,秋招季,也在忙着备战笔试面试.今天得空再来写一篇文章,本篇要讲解的内容是关于 Object.creat()基础 ,那今天这篇看能不能问倒你了,一起来探 ...

  5. (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上)

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...

  6. 原生JS灵魂之问(中),看看你是否熟悉JavaScript?

    笔者最近在对原生JS的知识做系统梳理,因为我觉得JS作为前端工程师的根本技术,学再多遍都不为过.打算来做一个系列,一共分三次发,以一系列的问题为驱动,当然也会有追问和扩展,内容系统且完整,对初中级选手 ...

  7. 【面试利器】 原生JS灵魂拷问,你能答上多少(一)

    前言 目前的前端世界,三大框架横行,原生JavaScript所用越来越少.但我认为JavaScript作为每一个前端工程师的立身之本,学再多遍都不为过. 因此我决定整理JavaScript中容易忽视或 ...

  8. 可以用于云原生中Skywalking框架原理你真的懂吗

    可以用于云原生中Skywalking框架原理你真的懂吗 ✨博主介绍 全链路监控 什么是全链路监控,为什么我们需要全链路监控? OpenTracing OpenTracing定位 OpenTracing ...

  9. 前端要懂mysql_【灵魂拷问】你真的懂得Mysql的管理和使用吗?

    作者 | Jeskson 来源 | 达达前端小酒馆 MySQL管理,数据库管理和数据表管理,用户管理. 初始化数据库,创建数据库,查看数据库,删除数据库. 创建数据表,查看数据表,修改数据表,删除数据 ...

最新文章

  1. mac 思科 链路聚合_TCP/IP协议栈-之-数据链路层分析
  2. 那个分分钟处理10亿节点图计算的Plato,现在怎么样了?
  3. CTO 写的代码,真是绝了
  4. python怎么打印出文件的内容,python怎么将打印输出日志文件
  5. svn 邮件通知及LOG处理 强制提交log日志
  6. DUILib 中的通知事件
  7. 鸿蒙适配倒计时,倒计时2天!首批鸿蒙OS适配名单确定,你的手机在列吗?
  8. CSS3 box flex 布局
  9. Inner Join, Left Outer Join和Association的区别
  10. hibernate 映射四多对一双向映射
  11. 三态输出门实验报告注意事项_数电基础知识:各种IO输出的类型
  12. 斯特林公式--求n!的位数
  13. centos7 挂载磁盘_Linux磁盘管理之LVM
  14. 第十五章:进程间通信
  15. 广东省惠州市谷歌卫星地图下载
  16. 通达信登录服务器文件夹,我也搞定了通达信交易系统多帐号登录交易!
  17. Pandas基础:列方向分组变形
  18. CSS数学函数- 阶梯值函数round() mode() rem()
  19. nssl 1467.U
  20. std::tr1::function

热门文章

  1. CE修改模拟器里的数据
  2. 震撼热聘: ZLG(周立功)集团诚聘软件工程师(多种职位!!!)
  3. 山西高平地域文化导入美术设计实训项目的实践
  4. 数据库面试题:对称加密和非对称加密的区别
  5. laypage 分页控件使用方法
  6. GitBook插件整理 - book.json配置
  7. 大概只有程序猿本猿才能看得懂的梗~
  8. vivoiqoo系统会加入鸿蒙吗,iqoo系统和vivo系统不一样 iqoo系统和vivo有什么区别 - 云骑士一键重装系统...
  9. LTG TWL 150/1064/N风机
  10. Redis | 跳跃表