每天多一点(2016.12.04)》Javascript隐式转换
乱想
javascript为什么需要隐式转换?如果没有会出现什么情况?
找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知。
郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲这样去想不太可能想出个结果,毕竟这门语言不是自己写的,如果换一个问题,可能会好点,如果没有隐式转换javscript会成什么样子?
比如下面这一段代码:
console.log("10" - 1)
如果没有隐式转换,也许会报错吧?或者返回NaN?,不太确定,但假如说javascript根本不存在隐式转换,或许你不会这样去写代码吧,那么就更奇怪了,设计隐式转换究竟何目的?目前能想到的一点就是因为它是一门动态语言,值是运行时才知道的,因此有很多不确定的因素,这可能是作者设计隐式转换的目的吧。
什么是隐式转换
console.log(1 + "2");//12
可以看到一个是Number类型的值和一个String类型的值进行了相加,结果是12。那为什么是12呢?如果是按照数字相加应该是3,但这里却是将1和2进行了字符串拼接,也就是说这里的1被转换成了字符串1。
结论
如果两个值(也可以是多个)的类型不同,但你却拿它们来运算,它们就会进行隐式转换,当然也不只是运算才会产生隐式转换。
谁被转换
console.log(10 + "2");//102
console.log(10 - "2");//8
console.log(10 * "2");//20
console.log("2" - 10);//-8
console.log(10 / "2");//5
它们有一个小小的规律,如果是+号,数字会被转换成字符串,而如果是减乘除则会将字符串转换成数字。
那么为什么唯独+号比较特别呢,因为在javascript中,+号是有两个作用的,一个是数字相加,另一个是字符串拼接,而javscript默认把这种情况当成了字符串拼接。另减乘除就不存在这种问题,因此也只好将字符串转换成数字。
哪些情况下会进行隐式转换
上面的几个例子中,都是在讲运算符导致的隐式转换,那么除了这种情况还有哪些情况下会进行隐式转换?
某些函数
isNaN():
console.log(isNaN(2)) //false
console.log(isNaN("a")) //true
console.log(isNaN("2")) //false
isNaN会将传进来的那个值进行转换如果能够转换成数字那么就是false(如果本身就是数字那么也是false),否则true。
条件判断
if(""){
console.log(true); //不会被打印
}
if(" "){
console.log(true); //会被打印
}
空字符串会被转换成false,否空字符串会被转换成true。
[0,-1,[],{},NaN,undefined,null,""," "].forEach(function(item,index){
if(item){
console.log(item);
}
})
// 打印的有:-1,[],{}," "
也就是除,非0的数字,数组,对象,非空字符串都会被转换成true,其他的false。
需要注意的是switch不会进行隐式转换
switch("5"){
case 5:
console.log(5);
break;
case "5":
console.log("5"); //打印这条
break;
}
如果switch会进行隐式转换那么问题就出大了,甚至我们都不敢去使用它。那么为什么if会进行隐式转换,我的理解是,因为if它的值无非就是true跟false,而你传进来的不是这种类型,它自然需要进行转换,switch则不同,它判断的是一个值是不是和另外一个值相等,因此它不能去转换,换一句话说switch使用的是 === 比较。
其他类型的混合运算
相加
console.log([]+0); //0
console.log(!+0); //true
console.log(!+1); //false
console.log(NaN+2); //NaN
console.log(NaN+"2"); //NaN2
console.log(NaN+"a"); //NaNa
console.log(undefined+0); //NaN
console.log(undefined+"0"); //undefined0
console.log(null+0); //0
console.log(null+"0"); //null0
console.log({}+0); //[object Object]0
console.log({}+"0"); //[object Object]0
console.log(""+0); //0
console.log(""+"0"); //0
console.log(true + 0); //1
console.log(true + "0"); //true0
console.log(false + 0); //0
console.log(false + "0"); //false0
- []》 0
- !》 会将后面的那个值转换成布尔类型,然后取反
- undefined 》 根据后面的那个值来进行转换,如果是数字转换成NaN,否则字符串拼接
- 》 [object Object]
- true 》 1
- false 》 0
其实有一个规律,除了[],,其他的值具体转换是根据和它进行运算的那个值的类型来转换的。
相减
console.log([]-0); //0
console.log(!-0); //true
console.log(!-1); //false
console.log(NaN-2); //NaN
console.log(NaN-"2"); //NaN
console.log(NaN-"a"); //NaN
console.log(undefined-0); //NaN
console.log(undefined-"0"); //NaN
console.log(null-0); //0
console.log(null-"0"); //0
console.log({}-0); //NaN
console.log({}-"0"); //NaN
console.log(""-0); //0
console.log(" "-"0"); //0
console.log("1"-"0"); //1
除了相加以为,其他的几个运算符,主要还是将这些值转换成数字进行运算,比较特殊的是!(取反),它始终转换成的是一个布尔值。
一些有趣的事
根据这些隐式转换,有时我们可以用它来做一些不同寻常的事,比如直接利用隐式转换来取得一个object字符串。
console.log(({}+0).substring(1,({}+0).indexOf(" "))) //object
原理因为+0等于 = "[object Object]0",既然它是一个字符串,那么我们可以用字符串的方法,将其中的某个值取出来,也可以用[]的方式来取值。
也就是利用这些隐式转换你可以取得任何字符串,甚至中文,不过需要你对javascript有点基础罢了。
console.log(String.fromCharCode(20013)) //中
取中文需要你知道对应的字符串编码值
隐式转换带来的利与弊
好处就是,我们不需要直接显示的进行转换,比如你想将一个字符串转成数字,只需要这样:
console.log("15"-0) //数字15
传统的做法
console.log(parseInt("15")) //数字15
但也有坏处,就是有些你并不希望进行转换,但它却转换了,而往往你容易忘了它会进行隐式转换这一点,导致一些不太明显的bug。
总结
大致会进行隐式转换的情况如下:
1、不同类型的值进行运算
2、判断
3、个别函数
问答
这两年越来越多讨论关于全栈工程师的话题,而实际上所谓的全栈工程师就是早期的程序员,那时分工没有现在这么明细,很多活都是一个人干,后来才开始分前端后端等,现在又开始所谓的全栈,你怎么看?如果你想成为一个全栈工程师,你会怎么做?
每天多一点(2016.12.04)》Javascript隐式转换的更多相关文章
- Javascript隐式转换
乱想 javascript为什么需要隐式转换?如果没有会出现什么情况? 找了一圈没有看到关于这个的讨论,只好自己研究了,可能不一定正确,自行辨知. 郁闷就是郁闷在好好的,为什么要搞个隐式转换,一般来讲 ...
- javascript隐式转换详解
Javascript是web前端开发的必学技术,今天和大家分享的就是javascript的基础知识隐式转换,希望可以帮助大家更好的学习. 转换成布尔类型假 undefined->falSe nu ...
- JavaScript 隐式转换
javascript 中的怪癖,js运算符隐式类型转换 x + "" //等价于 String(x) + x //等价于 Number(x),也可以写成x-0 !!x //等价于 ...
- 12、scala隐式转换与隐式参数
一.隐式转换 1.介绍 Scala提供的隐式转换和隐式参数功能,是非常有特色的功能.是Java等编程语言所没有的功能.它可以允许你手动指定,将某种类型的对象转换成其他类型的对象. 通过这些功能,可以实 ...
- JavaScript的六种数据类型与隐式转换
一.六种数据类型 javascript的数据类型包括: (1)基本数据类型:number.string.boolean.null.undefined (2)对象:object object又包括Fun ...
- null的坑 和 比较运算符、相等运算符的隐式转换问题 (在javascript中,null>=0 为真,null<=0 为真,null==0却为假,null到底是什么?)
null在关系运算中的坑 & 关系运算符的隐式转换问题 注意: 比较运算符 和 相等运算符 的 ECMAscript 语法实现不同. 比较运算符 和 相等运算符 对数据进行了隐式转换, 相当于 ...
- JavaScript学习笔记——数据类型强制转换和隐式转换
javascript数据类型强制转换 一.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 B.如果是数字,转换成为本身.将无意义的后导 ...
- javascript笔记整理(数据类型强制/隐式转换 )
A.数据类型强制转换 1.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 var a=false;alert(Number(a)); ...
- JavaScript的隐式转换
原文:JavaScript的隐式转换 JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object.object是引用类型,其它 ...
随机推荐
- java function retry wrapper
import java.util.concurrent.Callable; /** * Created by huahui.yang on 1/29/16. */ public class Retry ...
- 16-1-27---图解HTTP(02)
图解HTTP第四章 返回结果的HTTP状态码 HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现错误等工作.4.1状态码告知从服务器端返回的请求结果 ...
- 批量设置select为默认项
app.$form.find("select").prop("selectedIndex", 0);
- 无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
SQLite部署-无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块 近期刚使用SQLite,主要引用的是System.Data.SQLite.dll这个dll,在部署到测试 ...
- 仿【Emmet】转【HTML】功能
一.定义正则表达式: var whitespace = "[\\x20\\t\\r\\n\\f]*", nvarcharEncoding = whitespace + " ...
- 基于zepto的H5/移动端tab切换触摸拖动加载更多数据
以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很 ...
- css3新属性object-fit,对页面img处理
1.http://my.xueh5.com/xh5639998239/detail-3661.html 针对其进行深度讲解推荐 http://www.zhangxinxu.com/wordpress/ ...
- 有关JVM配置参数含义
1.参数的含义-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M-vmargs 说明后面是VM的参数,所以后面的其实都是JV ...
- SQL Server2000清除数据库日志
sqlserver2000压缩日志 可以将jb51.ldf文件变得很小,方便备份数据库等,在sqlserver查询分析器中执行即可.复制代码 代码如下: DUMP TRANSACTION [jb51] ...
- java学习之面向对象(2)
在描述事物的时候,该事物已存在就具备的一些内容,这是我们就可以把它们都定义在构造函数中,那么什么是构造函数呢? 构造函数就是构建创造对象时调用的函数,它可以给对象进行初始化.构造函数与类名相同,第一个 ...