JS隐形,显性,名义和鸭子类型
隐形转换
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隐形,显性,名义和鸭子类型的更多相关文章
- js设计模式--鸭子类型
1.简介 JavaScript没有提供传统面向对象语言的类式继承通过原型委托的形式实现对象与对象之间的继承没有对抽象类和接口的支持 编程语言按数据类型可分为静态类型语言和动态类型语言 变量的类型要到程 ...
- day25 多继承、接口、抽象类、鸭子类型
今日内容: 如何查看对象的名称空间及对象名 继承的另一种使用 单继承与多继承 经典类与新式类 mro列表 菱形继承 接口 抽象类 鸭子类型 1.查看名称空间包含的变量: 使用类或对象名.__dict_ ...
- 什么是“鸭子类型(duck typing)”?
在计算机编程世界里会接触到一个知识点 —— duck typing,叫“鸭子类型”. 它有一个形象的解释: “当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子. ...
- 鸭子类型duck typing(动态)
在程序设计中,鸭子类型(duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于由Ja ...
- duck type鸭子类型
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于 ...
- Javascript:由 “鸭子类型” 得出来的推论
Javascript:由 “鸭子类型” 得出来的推论 背景 学动态语言的都知道一句话:“如果它走起来像鸭子,而且叫起来像鸭子,那么它就是鸭子”,Javascript也支持鸭子类型,下文就说说鸭子类型在 ...
- python 鸭子类型
首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不 ...
- python之类的多态(鸭子类型 )、封装和内置函数property
一.多态 1.什么是多态:一个类表现出的多种状态--->通过继承来实现的例如:class Animal:passclass Dog(Animal):passclass Cat(Animal):p ...
- 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理
''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...
随机推荐
- CF80B Depression 题解
Content 有一个时针,给定时间为 \(\text{HH}\) 时 \(\text{MM}\) 分,求图中 \(\alpha\) 和 \(\beta\) 角的值. 手画勿喷/kk 数据范围:\(0 ...
- Django modules模块
http://www.cnblogs.com/wupeiqi/articles/5246483.html
- element UI遇到的问题
1. 在el-dialog中获取el-table的ref为undefined 问题:虽然设置了el-dialog的visible为true,但此时Dom并没有更新,因此在Dom更新前取不到el-tab ...
- JAVA验证身份证号码是否正确
package com.IdCard; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.D ...
- 【LeetCode】1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 Check If a String Contains All Binary Codes of Size K
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计长度为 K 的子串个数 日期 题目地址:https ...
- 【九度OJ】题目1183:守形数 解题报告
[九度OJ]题目1183:守形数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1183 题目描述: 守形数是这样一种整数, ...
- python-mysql-replication原理分析
源码地址:https://github.com/noplay/python-mysql-replication 文件解析: ├── binlogstream.py ├── bitmap.py ├── ...
- Theoretically Principled Trade-off between Robustness and Accuracy
目录 概 主要内容 符号说明 Error Classification-calibrated surrogate loss 引理2.1 定理3.1 定理3.2 由此导出的TRADES算法 实验概述 代 ...
- 【Linux】Linux安装JDK
1.下载linux版本的JDK1.8 链接:JDK下载链接 提取码:fxn4 链接:Xshell下载链接 提取码:439l 2.使用Xshell连接虚拟机,上传文件 在 /usr目录下创建一个新文件夹 ...
- VMware客户端vSphereClient新建虚拟机
1.说明 VMware客户端工具vSphere Client, 用来连接和管理ESX或ESXi主机(下面称为宿主机), 可以方便的创建.管理虚拟机,并分配相应的资源.宿主机就是使用虚拟化软件运行虚拟机 ...