隐形转换

  JavaScript中只有在一些极少数的情况下才会因为一个类型错误抛出错误。例如:调用非函数对象或者获取null / underfined的属性时,这就是隐形转换。

  首先JS在遇到运算符的时候(-、*、/、%)的时候会将在运算之前把运算符左右两边转换成为数字类型。

  

原始值 转化为数字类型 转换为字符串类型 转化为Boolean类型
false 0 'false' false
true 1 'true' true
0 0 '0' false
1 1 '1' true
'0' 0 '0' true
'1' 1 '1' true
NaN NaN 'NaN' false
Infinity Infinity 'Infinity' true
-Infinity -Infinity '-Infinity' true
'' 0 '' false
'20' 20 '20' true
"twenty" NaN 'twenty' true
[] 0 '' true
[20] 20 '20' true
[10,20] NaN '10,20' true
['twenty'] NaN 'twenty' true
['ten','twenty'] NaN 'ten,twenty' true
function(){} NaN 'function(){}' true
{} NaN [object,Object] true
null 0 'null' false
underfined NaN 'underfined' false

  但是遇到+号时,则会有多种情况

情况1. 运算中含有字符串

1 1+'2'        //'12'
2 '1'+2 //'12'
3 1+2+3+'4' //'54'

情况2. 运算中不含有字符串

1 1+2+3+4+5         //15

情况3. 运算中含有Bollean值,JS会将Boolean转换为数字,再进行运算。

1 1+true        //2

  遇到比较运算的时候也会触发隐形转换。

1 if(1==true){
2 alert('true');
3 }else{
4 alert('false');
5 }

当某个对象出现在了需要原始类型才能进行操作的上下文时,JavaScript 会自动调用 ToPrimitive 函数将对象转化为原始类型,而在ES6后,JS会优先调用对象的[Symbol.toPeimitive]方法来将对象转化为原始类型。

 1 var ToPrimitive = function(obj,preferredType){
2 var APIs={
3 typeOf:function(obj){
4 return Object.prototype.toString.call(obj).slice(8,-1);
5 }.
6 //判断是否原始对象的方法
7 isPrimitive:function(obj){
8 var _this = this,
9 type=['Null','Undefined','String','Boolean','Number'];
10 return types.indexOf(_this.typeOf(obj)) !== -1 ;
11 }
12 } ;
13
14 //如果obj本身就是原始对象, 则直接返回
15 if(APIs.isPrimitive(obj)){ return obj; }
16
17 //Date类型会优先调用toString方法,否则优先调用valueOf方法
18 preferredType = ( preferredType === 'String' ||
19 APIs.typeOf(obj) === 'Date' ) ? 'String': 'Number';
20
21 if(preferredType === 'Number'){
22 if(APIs.isPrimitive(obj.valueOf())){ return obj.valueOf()};
23 if(APIs.isPrimitive(obj.toString())){ return obj.toString()};
24 }else{
25 if(APIs.isPrimitive(obj.toString())){ return obj.toString()};
26 if(APIs.isPrimitive(obj.valueOf())){ return obj.valueOf()};
27 }
28 //否则抛出错误
29 throw new TypeError('TypeError');
30 }

可以看出转化的本质就是使用toString/valueOf,我们也可以通过覆写的方式来让数值在转换时达到我们理想的结果。

  工具类函数JSON.stringify()在将JSON对象序列化为字符串时也是调用了toString。

对于大多数基本数据类型,JSON.stringify()的效果和toSrting基本相同,只不过序列化的结果总是字符串。

1 JSON.stringify(42);        //"42"
2 JSON.stringify("66"); //""66"" (含有双引号的字符串)
3 JSON.stringify(null); //"null"
4 JSON.stringify(true); //"true"

JSON.stringify()在对象中遇到underfined、function、symbol时会自动忽略,在数值中遇到则会返回null(保持原来的位置)。

1 JSON.stringify( underfined );            //underfined
2 JSON.stringify(function(){}); //underfined
3 JSON.stringify([1,underfined,3,function(){},4]) //[1,null,3,null,4]
4 JSON.stringify({a:1,b:function(){}}) //{a:1}

显性转换

  方法1.使用内建函数

1 String(123);        //"123"
2 Number("123“) //123

这里的String是直接调用toString来转换字符串的,与”+“通过ToPrimitive的运作的不一样的。

JS隐形,显性,名义和鸭子类型的更多相关文章

  1. js设计模式--鸭子类型

    1.简介 JavaScript没有提供传统面向对象语言的类式继承通过原型委托的形式实现对象与对象之间的继承没有对抽象类和接口的支持 编程语言按数据类型可分为静态类型语言和动态类型语言 变量的类型要到程 ...

  2. day25 多继承、接口、抽象类、鸭子类型

    今日内容: 如何查看对象的名称空间及对象名 继承的另一种使用 单继承与多继承 经典类与新式类 mro列表 菱形继承 接口 抽象类 鸭子类型 1.查看名称空间包含的变量: 使用类或对象名.__dict_ ...

  3. 什么是“鸭子类型(duck typing)”?

    在计算机编程世界里会接触到一个知识点 —— duck typing,叫“鸭子类型”.   它有一个形象的解释: “当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子. ...

  4. 鸭子类型duck typing(动态)

    在程序设计中,鸭子类型(duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于由Ja ...

  5. duck type鸭子类型

    在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于 ...

  6. Javascript:由 “鸭子类型” 得出来的推论

    Javascript:由 “鸭子类型” 得出来的推论 背景 学动态语言的都知道一句话:“如果它走起来像鸭子,而且叫起来像鸭子,那么它就是鸭子”,Javascript也支持鸭子类型,下文就说说鸭子类型在 ...

  7. python 鸭子类型

    首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不 ...

  8. python之类的多态(鸭子类型 )、封装和内置函数property

    一.多态 1.什么是多态:一个类表现出的多种状态--->通过继承来实现的例如:class Animal:passclass Dog(Animal):passclass Cat(Animal):p ...

  9. 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理

    ''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...

随机推荐

  1. loger4j时间一长,就不向数据库里写日志啦,然而重新启动工程后就可以再次向数据库写日志,好奇怪

    loger4j时间一长,就不向数据库里写日志啦,然而重新启动工程后就可以再次向数据库写日志,好奇怪

  2. wordpress页面F12时源码多出的内容在index.php header.php找不到

    wordpress页面按F12时源码多出的内容在index.php header.php找不到 比如类似这样的内容: <div style="position:absolute;fil ...

  3. Dockerfile使用OracleJDK创建自定义tomcat8镜像

    我们默认下载的tomcat镜像是用的openjdk ,但是我们有些项目必须使用oraclejdk 那就不能使用官方的tomcat镜像,只能重新自定义一个镜像 Dockerfile文件 FROM cen ...

  4. 页码pageNo与SQL的limit进行换算

    /** * 计算出页码 */ public static int getPageNo(int pageNo,int pageSize){ if (pageNo<=1){ return 0; } ...

  5. 【LeetCode】1111. Maximum Nesting Depth of Two Valid Parentheses Strings 有效括号的嵌套深度

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目讲解 划分规则讲解 返回结果讲解 解题方法 代码 日期 题目地址:ht ...

  6. 【LeetCode】281. Zigzag Iterator 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 deque 日期 题目地址:https://leetc ...

  7. 【LeetCode】11. Container With Most Water 盛最多水的容器

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:盛水,容器,题解,leetcode, 力扣,python ...

  8. 【LeetCode】795. Number of Subarrays with Bounded Maximum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 暴力搜索+剪枝 线性遍历 日期 题目地址: ...

  9. 【LeetCode】858. Mirror Reflection 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  10. The Best Path

    The Best Path Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...