当前位置: 首页 > Web前端 > JavaScript

【深入06】隐式转换与运算符

时间:2023-03-26 21:49:16 JavaScript

导航[[深入01]执行上下文](https://juejin.im/post/684490...[[深入02]原型链](https://juejin.im/post/684490...[[深入03]继承](https://juejin.im/post/684490...[[深入04]事件循环](https://juejin.im/post/684490...[[深入05]CurryingPartialfunction函数记忆](https://juejin.im/post/684490...[[深入06]隐式转换与运算符](https://juejin.im/post/684490...[[深入07]浏览器缓存机制(http缓存机制)](https://juejin.im/post/684490...[[深入08]前端安全](https://juejin.im/post/684490...[[深入09]DebounceThrottle](https://juejin.im/post/684490...[[深入10]DebounceThrottle](https://juejin.im/post/684490...[[深入11]前端路由](https://juejin.im/post/684490...[[深入12]前端模块化](https://juejin.im/post/684490...[【深入13】观察者模式发布订阅模式双向数据绑定】(https://juejin.im/post/684490...[[深度14]画布](高ttps://juejin.im/post/684490...[[深入15]webSocket](https://juejin.im/post/684490...[[深入16]webpack](https://juejin.im/post/684490...[[深入17]http和https](https://juejin.im/post/684490...[[深入18]CSS-interview](https://juejin.im/post/684490...[[深入19]手写承诺](https://juejin.im/post/684490...[[深入20]手写功能](https://juejin.im/post/684490..[[react]Hooks](https://juejin.im/post/684490...[[部署01]Nginx](https://juejin.im/post/684490...[[部署02]DockerDeployvue项目](https://juejin.im/post/684490...[[部署03]gitlab-CI](https://juejin.im/post/684490...[[source-webpack01-front知识集]AST抽象语法树](https://juejin.im/post/684490...[[源码-webpack02-pre-knowledge]Tapable](https://juejin.im/post/684490...[[源码-webpack03]手写webpack-compiler简单编译过程](https://juejin.im/post/684490...[[源码]ReduxReact-Redux01](https://juejin.im/post/684490...[[源码]axios](https://juejin.im/post/684490...[[源码]vuex](https://juejin.im/post/684490...Number、String、Boolean的强制转换js是动态类型语言,变量没有类型限制,可以是任意赋值虽然变量的数据类型不确定,但是各种(运算符)对变量的(数据类型)有限制Number()强制转换参数:两种情况,参数为原始类型的值,参数为对象结果:将任意数据类型转换为值,value或NaN数字转换优于标准杆seInt是严格的,只要一个字符不能转换成值,整个字符串都会被转换成NaNNull=>0undefined=>NaNNumberparameter:原始类型Number()参数的值是原始类型1的值。当为0时,Number(false)Number('')Number(Null)2。当为NaN时,Number(undefined)Number('123abc')//不能转为数值的字符串//Number比parseInt严格,只要一个字符不能转为数值,则整个字符串将被转换为NaN//parseInt('123abc')//123//Number('123abc')//当NaN3。为1,Number(true)Number参数:当对象Number()的参数类型为对象时,只要不是单值数组,都会转为NaNNumber()。参数为对象Number([7])//7Number([1,2])//NaNNumber({a:1})//NaNNumber具体转换规则Number具体转换规则1.调用对象??的valueOf方法自身——如果返回原类型的值,直接使用Number函数,不进行后续步骤——如果返回对象,继续判断2.valueOf返回对象,然后调用对象的toString方法自身——如果返回的是原类型的值,直接使用Number函数,不进行后续步骤——如果返回object,则继续判断3.toString返回一个对象,则报错总结:valueOf=>object=>toStirng=>object=>上面步骤报错,如果返回的是原类型的值,则调用Number(),并终止后续步骤//valueOf:object的valueOf返回对象本身//toString:对象的toString返回对象的字符串形式//valueOf和toString可以自定义String()转换,将任何类型的值转换为字符串参数:原始类型或对象的值结果:字符串String()转换参数:原始类型的值String(123)//"123"String('abc')//"abc"String(true)//"true"String(undefined)//"undefined"String(null)//"null"参数:对象参数是对象,返回类型是字符串。参数为数组,返回数组的字符串形式。String({name:'woow_wu7'})//参数为对象,返回类型为字符串==>'[objectObject]'String([1,2])//参数为数组,返回数组的字符串形式,==>'1,2'具体转换规则调用对象的toString方法如果返回的是原始类型的值,使用String()方法转换if返回的是一个对象,继续下面的步骤调用对象的valueOf方法如果返回的是原始类型的值,使用String()方法转换如果返回的是对象,继续下面的步骤valueOf返回对象,然后报报错总结:以上步骤先调用toString()->object->valueOf()->Object->报错。如果返回原始类型的值,则调用String()并中止后续步骤//当String参数为对象时//参数为对象:返回类型字符串//参数为数字:返回字符串形式的数组Boolean()将任意类型的值转换为布尔值布尔类型转换除了以下6个值为false,其他均为trueBoolean(+0)//falseBoolean(-0)//falseBoolean('')//falseBoolean(null)//falseBoolean(undefined)//falseBoolean(NaN)//false自动转换和自动转换发生在不同类型的数据对非Boolean数据相互操作得到Boolean的值时非数值类型,使用一元运算符自动转换规则期待任意类型的值,然后调用该类型的转换函数自动转换为字符串。字符串的自动转换主要发生在添加字符串的时候。值是字符串,另一个值是非字符串,添加,非字符串转换为字符串'5'+1//'51''5'+true//"5true"'5'+false//"5false"'5'+{}//"5[对象Obobject]"======>{}=>toString=>返回类型字符串'[objectObject]''5'+[]//"5"=====================>[]=>toString=>返回数组的字符串形式''=>'5'+'''5'+function(){}//"5function(){}"'5'+undefined//"5undefined"'5'+null//"5null"自动转为值除了+可能会把运算符转成字符串,其他运算符都会转运算符转换为数字一元运算符还将运算符转换为数字'5'-'2'//3'5'*'2'//10true-1//0false-1//-1'1'-1//0'5'*[]//0----------------------5*0false/'5'//0-----------------------0/5'abc'-1//NaN-----------------------NaN-1null+1//1--------------------------0+1undefined+1//NaN--------------------NaN+1一元运算符也会将运算符转换为值+'abc'//NaN-'abc'//NaN+true//1-false//0运算符加法operatoroverload(过载):还有addi加法运算符的重载和连接,不同的运算符导致不同的语法行为。除了加法运算符,其他运算符都没有重载,将运算符转换为值,然后进行数学运算如果运算符是对象,则必须先将对象转换为原始类型的值,然后加上true//2'a'//"1a"--------------------Values和strings是新加入的,+又存在了重载,所以1被转换为字符串'1'=>'1a'(2)重载导致不同的结果'3'+4+5//"345"4+'5'//"75"----------注意顺序不同的结果(3)运算符是一个对象varobj={p:1};obj+2//"[objectObject]2"------valueOf=>对象本身{p:1}=>toString()=>'[objectObject]'+2=>'[objectObject]2'------对象的valueOf返回对象本身--------注意:添加字符串和数字,因为+被重载了,此时+表示连接------注意:toString()之后,+被重载了,Number()也可能被调用可以调用String()null和undefinednull和undefined严格等于它们自己undefined===undefined//truenull===null//truevarv1;//undefinedvarv2;//undefinedv1===v2//true相等运算符==相等运算符,当用于比较同类型数据时,相当于严格相等运算符同类型数据:==和===相当于不同类型的数据:==会先进行类型转换,然后用===比较原始类型数据:转换成值,再比较对象类型数据:先将对象转换成原始类型值,然后比较null和undefined:相互比较true,和比较任何其他类型为false缺点:有隐式转换,容易出错。原始类型的值:先转为值,再进行比较==true//true//等价于1===Number(true)'true'==true//false//都转为数值values//相当于Number('true')===Number(true)//相当于NaN===1'1'==true//true//相当于Number('1')===Number(true)//等价于1===1false=='false'//false//Number(false)==Number('false')=>0===NaN=>falsefalse=='0'//true对象类型的值:先转换对象转换成原始类型的值,然后比较[1]==1//true//等价于Number([1])==1[1]=='1'//true//等价于Number([1])==Number('1')[1]==true//true//等同于Number([1])==Number(true)null和undefined:相互比较true,任何其他类型的falsefalse==null//falsefalse==undefined//false==null//false==undefined//falseundefined==null//truefalse==undefined//false----------------undeined与null和任何其他类型比较==,都返回false,mutual==返回true--------------原理:Number(false)==Number(undefined)=>0===NaN=>falsefalse==null//falsenull==undefined//truepriority最高优先级:属性访问具有最高优先级。()最低优先级:赋值运算符=优先级最低的运算符,一元运算符在结合性具有相同优先级时具有最高优先级,例如乘法和除法,当优先级相同时,考虑结合性Associativity分类:左结合和右结合右结合:一元运算符,三元运算符,赋值运算符为右结合,其他运算符均为左集合左结合:其他为左结合运算从左到右依次是isNaN和Number.isNaNisNaN()先把参数转换成number类型,再用isNaN判断Number.isNaN()先判断参数是否为number类型,不返回false,然后用isNaN判断varn=1/'foo'vara='str'console.log(n)//1/Number('foo')=>1/NaN=>NaNconsole.log(n==NaN)//NaN==NaN=>falseconsole.log(NaN===NaN)//falseconsole.log(isNaN(n))//真正的控制台。log(isNaN(a))//isNaN(Number('str'))=>isNaN(NaN)=>trueconsole.log(Number.isNaN(n))//Number.isNaN('str')=>trueconsole.log(Number.isNaN(a))//Number.isNaN()先判断参数是否为Number类型,false返回false,true再用isNaN判断=>直接falsecase1[]==![]//真正的分析:1.优先级:!>==所以先数吧![]=>false//除了'',+-0,null,undefined,NaN为true,其他为false2。[]==false3。=当=等于运算符的运算符有对象时,先将[]转换为原始类型的值,然后进行比较4.Number([])==false=>valueOf=>[]=>toString=>''=>数字('')=>0==false5。0==假6。0==Number(false)=>0==0相同类型==等于====>0===0=>true7。trueCase2[]+[]//''分析:1.+的运算符是一个对象,先转换为原类型的值,然后加上2.[]=>valueOf([])=>[]=>toString([])=>''3。''+''4。字符串加法,+存储在过载中,此处表示连接5。''