zoukankan      html  css  js  c++  java
  • JS笔记(二):隐式转换

    最近刚开始复习JS的基础知识,看到隐式转换这一块发现它的规则很多,红宝书上列出的框框又有些冗杂,所以这里我根据自己的理解总结一下其中主要的隐式转换规律。

     

    1、== 操作符

      1)若存在Boolean类型 :比较相等性之前先将其转换为数值,true == 1、false == 0

      2)若存在一String类型另一数值型:比较之前先将其转换为数值,调用Number(str)

      3)若存在一Object类型另一其它:调用对象的valueOf()方法,得到基本类型后再按照前面的规则进行比较。

    2、Number() 可将任意类型转换为数值型

      1)true==1、false == 0、“” == 0(空字符串)

      2)识别多种进制,格式正确返回数字,格式错误返回NaN

      十六进制0XA转换为十进制数字10,而后者格式无法识别返回NaN。

      3)操作数为对象时,先执行对象的valueOf(),若转换结果为NaN则调用对象的toString()方法。

      

      数组的valueOf()方法返回数组自身,toString()返回空字符串转换为数值0。

      

      对象的valueOf()方法返回对象本身,toString()返回一个对象类型名称字符串无法转换为数值返回NaN。

    3、位运算符  非数值型Number()隐式转换后运算

      1) ~ 按位非(操作数的相反数-1)

      2) & 按位与(相同为1不同为0)

      3)  |  按位或(有一个为1就是1)

      4) ^ 按位异或(相同为0不同为1) 

      5) << 左移(不影响符号位)n<<m == n*2m

      6) >> 有符号右移(保留符号位)n>>m==n/2m

      7) >>> 无符号右移(会将负数的二进制码(补码)当作正数的二进制码运算)

    4、逻辑运算符

      1)!逻辑非 仅返回布尔值(!! 相当于 Boolean(),将任意类型转换为布尔型)

      2) || 逻辑或:一真则真两假为假

      第一个操作数为假时返回第二个操作数;

      第一个操作数为真时返回第一个操作数。

      

      3) && 逻辑与:一假则假两真为真

      第一个操作数为假时返回第一个操作数;

      第一个操作数为真时返回第二个操作数。

      

      注:上述规则适用于任何操作数类型,为真(true、非空str、非零数值、任何对象),为假(false、空str、0、NaN、Null、undefined)

    5、++/--自增自减操作符

      先对非数值操作数进行隐式Number()转换,后执行加一或减一操作。 

    6、加减以及乘性运算符

      1)+、- 实现字符串和数值的相互转换

      字符串转换为数值:+"10" === 10 (非数值+/-操作时应用Number()转换规则)

      数值转换为字符串:10+"" === "10" (此处加号作为字符串拼接符,对数值调用toString()方法)

      2)*、/、%

      同样对非数值调用Number()后进行运算操作。

      注:% 运算符运算结果的符号取决于第一个操作数。

    7、优先级问题(图偷来的)

      

    8、隐式转换应用

      

      相信不少人都见过上面这一式子,乱七八糟的符号堆在一起,像我这样的初学者一看根本不知道是什么,更想不到它还能返回结果。

      接下来我就结合之前列出的一些规律简单解析一下这个式子,来看看其中的隐式转换是如何起作用并返回正确结果的。

      1)整体分析抽出骨架

      

      2)Part A  :   ( ! ( ~ + [ ] ) + { } )

      !(~ + [ ]) 加号在这里起正号作用,+[ ]经过Number()隐式转换返回0,而对0取反返回-1,最后逻辑非返回false。

      

      于是式子简化为( false + { } ),加法运算符调用Number(),上面已经说过{ }最后会调用toString()方法,进而式子变成了( false+"[object Object]" ),加法运算符碰到字符串又变成了字符串拼接符。

      

      3)Part B  :  [ --[ ~ + "" ][ +[ ] ] * [ ~ + [ ] ] + ~~! +[ ] ]

      先按将式子按隐式转换规律简化(依旧是Number())

    [ --[ ~ + "" ][ +[ ] ] * [ ~ + [ ] ] + ~~! +[ ] ];
    
    [ --[ ~ + 0 ][ 0 ] * [ -1 ] + ~~!0 ];
    
    [ --[ -1 ][ 0 ] * [ -1 ] + ~~true ];
    
    [ --( -1 ) * [ -1 ] + 1 ]; //两次取反返回自身
    
    [ -2 * [ -1 ] + 1 ]; //自增减运算符优先级高于*运算符
    
    [ 2 + 1 ]; 

      4)Part A + B = what?

      ("flase[object Object]")[3],这不就是按索引访问字符串中的值嘛,返回结果"s";

      下面也是同样套路。

      5)Part C

      两个对象最后各自调用了toString()方法,得到字符串。

      

      6)Part D  

    [ [ ~! + [ ] * ~ +[ ] ] ];
    
    [ [ ~true * -1 ] ];
    
    [ [ -2 * -1 ] ];
    
    [ [ 2 ] ]; 

      这里包裹的两层中括号,实际上也是应用了隐式转换,内层的数组 [2] 调用toString()最终返回数值 2;

      

      7)最后,"s"+"b"拼接起来就出现了前面的返回结果。

    总结:

      坦白讲,像上面那样的式子除了出现在面试题中其他地方肯定是见不到的,但这也给了我们一些启示。他的隐式转换是后台自动调用的,这就增加了一些不可控性,另外自动的隐式转换还会引起额外的性能消耗。应该尽量避免隐式转换的使用让程序更稳定。

  • 相关阅读:
    unity3d 免费好用的数据库处理框架 数据库直连框架
    为.NET搭建Linux的开发环境,鄙视那些将简单事情复杂化的人
    为Linux重新开发MVC,有图有真相
    让我们一起用开源数据库和开源框架废弃Access
    C#子线程执行完后,调用主线程的方法
    javascript 将 table 导出 Excel ,可跨行跨列
    Easyui中 messager.alert 后某文本框获得焦点
    Easyui中 alert 带回调函数的 消息框
    wamp 在本地安装PHP环境, 开启 curl 扩展
    H+ 编辑tab页 保存后 刷新列表tab页 并关闭自已。tabA页调用tabB页的方法
  • 原文地址:https://www.cnblogs.com/qimeng/p/7172182.html
Copyright © 2011-2022 走看看