JavaScript显式类型转换与隐式类型转换
在 JavaScript 中声明变量不需指定类型,对变量赋值也没有类型检查,同时还允许隐式类型转换。 这些特征说明 JavaScript 属于弱类型的语言。
在强类型的 C++ 中,多数情况下构造函数需要声明为 explicit 来禁止隐式类型转换, 避免误用(见Item 15:资源管理类需要提供对原始资源的访问)。 弱类型的 JavaScript 中没有这一机制,比如下面的代码:
// 弹出对话框中输入1
var a = prompt('input a number');
var b = a + 1;
console.log(b); // 控制台输出 11
目前 JavaScript 还无法阻止 a 被隐式转换为字符串。 本文便来总结一下 JavaScript 的类型转换行为,以及隐式类型转换的规则。
转换为字符串
转换为字符串是应用程序中的常见操作,几乎所有语言都提供了将任何类型转换为字符串的通用接口。 比如Java和C#的toString方法、C++的函数std::to_string,当然还有JavaScript的toString方法。
多数的JavaScript宿主环境(比如Node.js和Chrome)都提供了全局函数toString; 与此同时Object.prototype也定义了toString方法,使得所有对象都拥有转换为字符串的能力。
比如一个Number转换为String:
var n = 1;
n.toString(); // '1'
toString接受一个参数指定进制,默认为10. 可以利用这个参数生成包括字母和数字的随机字符串:
Math.random().toString(36).substr(2);
random生成一个0到1的随机数,36进制的字符集为[0-9a-z](36个),substr用来截掉起始的"0."。 另外Object.prototype.toString可以用来检测JavaScript对象的类型:
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
// Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
// 自定义类型
toString.call(new MyClass); // [object Object]
转换为数字
字符串转换为数字也是常见需求,通常用来从用户输入或文件来获得一个Number。 在C++中可以用atoi、cin、scanf等函数,在JavaScript中可以直接用parseInt和parseFloat。 例如:
var iNum1 = parseInt("12345red"); //返回 12345
var iNum1 = parseInt("0xA"); //返回 10
var iNum1 = parseInt("56.9"); //返回 56
var iNum1 = parseInt("red"); //返回 NaN
var fNum4 = parseFloat("11.22.33"); //返回 11.22
注意NaN是JavaScript中唯一一个不等于自己的值。(NaN == NaN) === false! 如果遇到非法字符,parseInt和parseFloat会忽略之后的所有内容。
parseFloat只接受十进制数字的字符串,而parseInt还提供了第二个参数(可选)用来指定字符串表示数字的进制:
var iNum1 = parseInt("10", 2); //返回 2
var iNum2 = parseInt("10", 8); //返回 8
var iNum3 = parseInt("10", 10); //返回 10
上述例子来自 w3school.com.cn: http://www.w3school.com.cn/js/pro_js_typeconversion.asp
强制类型转换
强制类型转换在C++中有两种方式:用括号将类型声明在变量之前;或者调用构造函数。 在JavaScript中没有类型关键字(只有一个var来声明变量),因而只能调用构造函数:
Boolean(0) // => false - 零
Boolean(new object()) // => true - 对象
Number(undefined) // => NaN
Number(null) // => 0
String(null) // => "null"
隐式类型转换
隐式类型转换是最为隐蔽的地方,不加注意的话很容易在这一点上出错,对这一点的掌握也体现了JavaScript程序员经验。 JavaScript会自动转换表达式中对象的类型以完成表达式求值。
四则运算
加法运算符+是双目运算符,只要其中一个是String类型,表达式的值就是一个String, 会隐式调用每个元的 .toString() 方法。
对于其他的四则运算,只有其中一个是Number类型,表达式的值便是一个Number。
对于非法字符的情况通常会返回NaN:
'1' * 'a' // => NaN,这是因为parseInt(a)值为NaN,1 * NaN 还是 NaN
不同类型的相加的行为比较复杂,也不一致,可以参考这里: https://www.andronio.me/2017/10/22/js-operators-incensistency/
判断语句
判断语句中的判断条件需要是Boolean类型,所以条件表达式会被隐式转换为Boolean。 其转换规则同Boolean的构造函数。比如:
var obj = {};
if(obj){
while(obj);
}
toString
有些接口只支持字符串参数,会对传入值进行 toString。 比如 JavaScript 宿主环境提供的接口:
alert({a: 1}); // => [object Object]
这里传入任何对象都会被 toString 转为字符串。
.
JavaScript显式类型转换与隐式类型转换的更多相关文章
- 「译」JavaScript 的怪癖 1:隐式类型转换
原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...
- C# 数据类型转换 显式转型、隐式转型、强制转型
C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...
- Java基础学习-类型转换之隐式转换
+是一个运算符,我们应该能够看懂,做数据的加法. boolean类型不能转换为其他的数据类型. 默认转换: byte,short,char--int--float--double by ...
- 转】C#接口-显式接口和隐式接口的实现
[转]C#接口-显式接口和隐式接口的实现 C#中对于接口的实现方式有隐式接口和显式接口两种: 类和接口都能调用到,事实上这就是“隐式接口实现”. 那么“显示接口实现”是神马模样呢? interface ...
- C# Interface显式实现和隐式实现
c#中对接口的实现方式有两种:隐式实现和显式实现,之前一直没仔细看过,今天查了些资料,在这里整理一下. 隐式实现的例子 interface IChinese { string Speak(); } p ...
- 多态设计 zen of python poem 显式而非隐式 延迟赋值
总结 1.python支持延迟赋值,但是给调用者带来了困惑: 2.显式而非隐式,应当显式地指定要初始化的变量 class Card: def __init__(self, rank, suit): s ...
- selenium-webdriver中的显式等待与隐式等待
在selenium-webdriver中等待的方式简单可以概括为三种: 1 导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2 隐式等待,直接调用i ...
- (java)selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待
selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待 本例包括窗口最大化,刷新,切换到指定窗口,后退,前进,获取当前窗口url等操作: import java. ...
- Java并发之显式锁和隐式锁的区别
Java并发之显式锁和隐式锁的区别 在面试的过程中有可能会问到:在Java并发编程中,锁有两种实现:使用隐式锁和使用显示锁分别是什么?两者的区别是什么?所谓的显式锁和隐式锁的区别也就是说说Synchr ...
- 大数据技术之_16_Scala学习_06_面向对象编程-高级+隐式转换和隐式值
第八章 面向对象编程-高级8.1 静态属性和静态方法8.1.1 静态属性-提出问题8.1.2 基本介绍8.1.3 伴生对象的快速入门8.1.4 伴生对象的小结8.1.5 最佳实践-使用伴生对象解决小孩 ...
随机推荐
- 201871010116-祁英红《面向对象程序设计(java)》第八周学习总结
项目 内容 <面向对象程序设计(java)> https://home.cnblogs.com/u/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.c ...
- Vue入门(二)
1.vue3.0安装 cnpm install -g @vue/cli 或者 yarn global add @vue/cli //创建项目 vue create hello-world //运行 n ...
- 2019徐州网络赛 I J M
I. query 比赛时候没有预处理因子疯狂t,其实预处理出来因子是\(O(nlog(n))\)级别的 每个数和他的因子是一对偏序关系,因此询问转化为(l,r)区间每个数的因子在区间(l,r)的个数 ...
- 第04组 Alpha冲刺(1/4)
队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(1/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.安排好各个组员的任务 2.收集各个组员的进度 3.写页面 4.写博客 展示Gi ...
- hyper-v简介及安装使用
前言:作为IT界的巨头,微软自己的虚拟化技术,也是微软第一个采用Vmware与CitrixXen一样基于hypervisor的虚拟化技术,有着自己可圈可点的地方,微软自己的虚拟化技术嘛,对windo ...
- sqoop的详细使用及原理
转自:https://blog.csdn.net/zhusiqing6/article/details/95680185 1.sqoop简介sqoop是一个用来将hadoop中hdfs和关系型数据库中 ...
- PageHelper使用以及PageInfo中分页对象的转化
在使用Mybatis查询数据库展示到前端的过程中不可避免的要考虑到分页问题,这时就引入了Mybatis的PageHelper插件,这个插件对分页功能进行了强有力的封装,只需要将查询出来的数据List集 ...
- 转 SSD论文解读
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u010167269/article/det ...
- 聊聊 Vue 中 title 的动态修改
由于之前的 Vue 项目打包成果物一直是嵌入集成平台中,所以一直没有关注过项目的 title.直到最近,突然有个需求,要求点击按钮在集成平台外新开一个页面,此时我才发现,原来我的项目的 title 一 ...
- CAD绘图大师都在用的46组快捷键,高效绘图必备
学习CAD 是一个需要慢慢积累的过程,千万不要遇到一点小困难就退缩,有困难我们就一起克服它!今天小编也是来帮助大家克服困难的!很多小伙伴学习CAD已经有一段时间了,但是发现自己的绘图效率还是不高,没关 ...