我们在写笔试题的时候,经常碰到涉及隐式转换的题目,例如

"1" + 2
obj + 1
[] == ![]
[null] == false

=== 和 ==

=== 叫做严格运算符,对象类型指向地址相同或原始类型( 数值、字符串、布尔值)值相同;==叫做相等运算符,类型不同会进行转化再比较,undefined、null相等,对象类型还是比较引用。==运算符将原始值和其包装对象视为相等,但===运算符将它们视为不等。 所有obj.a==null(相当于obj.a=== null || obj.a ===undefined)。

相等运算符就是常常引起JS隐式转换的坑货,它也常常出现在我们的面试题中,不过我们在现实开发中,为了避免不必要的问题要求使用严格运算符,但是了解还是很有必要的。

想要了解JS隐式转换,就要先从三个知识点下手。

原始类型

原始类型(基本类型、基本数据类型、原始数据类型)是一种既非对象也无方法的数据。在 JavaScript 中,共有7种:string,number,bigint,boolean,null,undefined,symbol (ECMAScript 2016新增)

falsy 值 (虚值)

falsy 值 (虚值) 是在 Boolean 上下文中认定为 false 的值,在JavaScript只有 七个 falsy 值。

  1. false false 关键字
  2. 0 数值 zero
  3. 0n 当 BigInt 作为布尔值使用时, 遵从其作为数值的规则. 0n 是 falsy 值.
  4. 一个空字符串 (字符串的长度为零). JavaScript 中的字符串可用双引号 "", 单引号 '', 或 模板字面量 `` 定义。
  5. null null - 缺少值
  6. undefined undefined - 原始值
  7. NaN NaN - 非数值

特别要说明的是,除了这七个对象全是真值,如new Number 和new Boolean 都是真值。

let b = new Boolean(false);i
f(b){//会执行到这里。
}

四大转换规则

  • toString规则:其他类型的值转换为字符串类型的操作

    • null => "null"
    • undefined => "undefined"
    • true => "true" false=>"false"
    • 10 => "10" "1e21"=>"1e+21"
    • [1,2,3] => "1,2,3"
    • Object对象 => "[Object Object]" 其实是调用toString方法
  • ToPrimitive规则:对象类型数组转为原始类型的操作

    • 当对象类型需要被转为原始类型时,它会先查找对象的valueOf方法,如果valueOf方法返回原始类型的值,则ToPrimitive的结果就是这个值
    • 如果valueOf不存在或者valueOf方法返回的不是原始类型的值,就会尝试调用对象的toString方法,也就是会遵循对象的ToString规则,然后使用toString的返回值作为ToPrimitive的结果
    • Date 是先toString再ValueOf
    • 如果在toString再ValueOf后都不能拿到原始类型,再判断相等、加减时就抛出Uncaught TypeError: Cannot convert object to primitive value
  • ToNumber规则

    • null=> 0
    • undefined => NaN
    • "123"=>123 "12ssd"=>NaN ""=>0
    • false => 0 true=>1
    • 数组、对象ToPrimitive
  • ToBoolean规则

    • js中七个falsy 值 (虚值) 为false,其他都为true

隐式转换

有了对上面知识点的认识,我们可以来一举拿下JS隐式转换了。

  • == 的过程(优先换成数字、字符串)
  1. 首先看==前后有没有NaN,有的话都是返回false。NaN不等于任何值,包括其本身
  2. 布尔值会转成数字类型,true转成1,false转成0
  3. 数字和字符串比较,字符串会转成数字
  4. undefined和null除了和undefined或null相等,和其他相比都是false
  5. 数字或者字符串和对象相比,对象使用ToPrimitive规则转换。
  6. 当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。
  • +的过程(优先换成字符串、数字)
  1. 如果至少有一个操作数是对象,它会被转换成原始值(字符串,数字或布尔);
  2. 转换之后,如果至少有一个操作数是字符串类型,第二个操作数会被转换成字符串,并且会执行连接。
  3. 在其他的情况下,两个操作数都会转换成数字并执行算数加法运算。
  • -的过程(转换成数字) 这个就很简单了,全部用ToNumber规则转换成数字

检测学习成果

我们根据以上所学看几个笔试题。如果你都知道结果,就不用看我的废解释了。

[] == []
[] == ![]
[null] == false

第一个,==左右都是对象,比较引用地址,这个两个不同的实例,肯定不相等啊。 第二个,!的优先级高于==,所以先 [] 是真值,求非当让是false了,转成数字0,==左是对象右是数字,对象使用ToPrimitive规则转换成"",再用ToNumber规则就转成0了,判断为相等。 第三个,[null]ToPrimitive再ToNumber规则就转成0,false也转成0。

var a = 1;
var b = "3";var obj1 = {i:1,toString:function() {return "1";},valueOf:function() {return 1;}
};
var obj2 = {i:1,toString:function() {return "2";}
};
var obj3 = {i:1,valueOf:function() {return 3;}
};
var obj = {i:1,
};
var objE = {i:1,valueOf:function() {return [];},toString:function() {return {};}
};a+b
a + obj
a + objE a+obj1
a+obj2
a+obj3  b+obj1
b+obj2
b+obj3  a==obj2
a==obj1

这道题比较简单你只要熟练掌握我上面说的那几个知识点可以了。下面直接写出结果啦。

a + b    //"13"
a + obj  //"1[object Object]"
a + objE //Uncaught TypeError: Cannot convert object to primitive valuea+obj1  //2
a+obj2  //"12"
a+obj3  // 4b+obj1  //"31"
b+obj2  //"32"
b+obj3  //“33”a==obj2  //false
a==obj1  //true

最后提一个比较奇葩的题目。

定义一个变量a,使得下面的表达式结果为true

a == 1 && a == 2 && a == 3

这里我简单提示下,a要是一个对象,重写valueOf方法,让它每次隐式转换的时候,调用时i++。

valueOf()在Object上默认返回的是对象不是原始类型,它会再调用toString。所以只要重写toString也可以。

如果还是没有思路,你们可以去看下这道题的文章原文从一道面试题说起—js隐式转换踩坑合集。

更多学习内容观看我的知乎

程序员的一切:打造全网web高级前端工程师资料库(总目录)看完学的更加快,知识更牢固。你值得拥有(持续更新)~​zhuanlan.zhihu.com

js date转成 时间字符串_秋招快要开始了,前端笔试中的坑位-JS隐式转换问题相关推荐

  1. mysql数据库隐式表_详解MySQL数据库常见的索引问题:无索引,隐式转换,附实例说明...

    概述 在这些年的工作之中,由于SQL问题导致的数据库故障层出不穷,而索引问题是SQL问题中出现频率最高的,常见的索引问题包括:无索引,隐式转换. 索引问题 1.无索引 当数据库中出现访问表的SQL无索 ...

  2. 艾为数字ic面试题_秋招 应聘FPGA/数字IC笔试面试经验分享(简单列举FPGA/数字IC公司)...

    1.自我介绍 我是一名二本院校的电气自动化专业的本科生,因为自己的爱好,喜欢FPGA开发,两年的开发经验,用FPGA开发并完成三个省级科研立项并获得一个A类竞赛国家一等奖.目前签约上海艾为电子,数字I ...

  3. 2021网易互联网秋招内推批前端笔试

    时间 2020.8.8,跟今年春招网易互娱的暑期实习题型一样,四道算法编程题,考试时间100分钟. 第一道很简单不多提,其他先 mark 下来,后面有空再慢慢总结答案(太菜了). 第二道 题目 有 E ...

  4. ios将时间戳转换成时间字符串类的方法源码

    如下代码段是关于ios将时间戳转换成时间字符串类的方法的代码,应该是对各位朋友有一些用途. { [dateFormat setDateFormat:formatString]; NSLog(@&quo ...

  5. 将一个十位数字的时间戳转换成时间字符串

    /**      * 将一个十位数字的时间戳转换成时间字符串      *   */     public static String convertTimeToFormat(long timeSta ...

  6. html中隐式转换成数字,关于 JS 类型隐式转换的完整总结

    作者:原罪 来源:SegmentFault 思否社区 不管是在技术聊天群还是论坛里,总能碰到 x + y 等于多少的问题,比如 ,如果你不了解其中的原理,那么就插不上话,只能眼睁睁地等大佬解答了. T ...

  7. js拼接字符串时数据类型的隐式转换

    数据类型的隐式转换:字符串类型string>数值类型number>布尔类型boolean数字+字符串:数字需要转成字符串 数字+布尔值:布尔值需要转成数字(true转成1,false转成0 ...

  8. js return的值取不到_【JS基础】隐式转换(一)

    开篇 JS作为一门动态语言十分灵活,但是伴随而来的弱类型隐式转化的问题让我们十分头疼. 隐式作为一个大课题,很难用一个很简短的篇幅把JS的隐式转换讲解的十分清楚.所以我选择用多次少量的策略进行梳理,争 ...

  9. 2022届秋招保利威前端面试

    2022届秋招保利威前端面试 原文网址:https://www.nowcoder.com/discuss/353158719997419520?sourceSSR=search 对象的浅拷贝和深拷贝如 ...

最新文章

  1. 基于“飞桨”的深度学习智能车
  2. 26 Java GC算法 垃圾收集器、标记 -清除算法、复制算法、标记-压缩算法、分代收集算法
  3. PHP面试题:写一个二维数组排序算法函数,能够具有通用性,可以调用php内置函数(array_multisort())
  4. C++泛型编程实现哈希表(闭散列---线性探测)
  5. linux cpu频率软件,linux cpu频率控制
  6. flash与CPU连接及flash属性描述文件
  7. 在计算机上配置超级终端,超级终端设置步骤【详细步骤】
  8. 苹果开发者计划许可协议(2017年5月2日)
  9. 实型变量(浮点型变量)、字符型数据、字符串常量(变量)、字符常量(变量)
  10. 服务器主板支持专用条,AMD专用条又要火了?在H110平台上竟然可以完美使用
  11. JavaScript编程精解(笔记1)
  12. The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
  13. x265 命令行参数大全(比较详细)
  14. BZOJ 3351 ioi2009 Regions
  15. python画xy轴_用python建立两个Y轴的XY曲线图方法
  16. linux 免费教程下载,Linux系统入门教程
  17. python接入excel_Excel 借助 Python 连接 WorkBench,实现 Excel 输入参数返回结果
  18. Hadoop——开源分布式计算平台简介
  19. RSD 教程 —— 1 安装 RSD
  20. [信息化]企业信息化规划建设中需要注意的点

热门文章

  1. c语言 返回函数是结构体指针变量,一个函数返回值为指向结构体的指针的问题...
  2. 【名额有限】云开发AI拓展能力等你来体验!
  3. 靠谱的Pycharm安装详细教程
  4. hdu5279 YJC plays Minecraft 【分治NTT】
  5. android UI布局
  6. Java开启/关闭tomcat服务器
  7. Html.Action、html.ActionLink与Url.Action的区别
  8. OpenGL ES 2.0 for iPhone Tutorial
  9. 309. Best Time to Buy and Sell Stock with Cooldown
  10. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第33篇]Bellcore攻击是如何攻击使用CRT的RSA的?