隐式转换的规则

问题:隐式转换的规则是什么

说起JS的隐式转换规则,我们可以说下JS的基础数据类型

JS的七中类型

我们所熟知的JS,可以在大体上可以分为2中类型:原始类型,复杂类型(对象类型)

原始类型

JS再继续细分的话,原始类型包含:stringnumber、boolean、nullundefined、symbol

对象类型

JS的对象类型包含:object

三种隐式转换类型

JS中一个难点就是隐式转换,因为JS在一些操作符下其类型会做一些变化,所以JS灵活,同时也会造成一些错误,并且难以理解

这其中涉及隐式转换最多的两个运算符 + ==

+运算符即可数字相加,也可以字符串相加,所以比较麻烦,== 不同于 ===,也存在隐式转换, *、/、-这些操作符都是针对number类型的,故转换的结果只能是转换成number

隐式转换中主要是三种转换方式:

  • 将值转换为原始值。toPrimitive(input,type?);
  • 将值转换为数字。toNumber()
  • 将值转换为字符串。toString()

通过toPrimitive()将值转换为原始值

ToPrimitive(input,PreferredType?)

input是要转换的值,Preferred是可选参数,可以是Number或者String类型。他只是一个转换标志。转换后的结果并不一定是这个参数所代表的类型,但是转换结果一定是个原始值或者是错误

ToPrimitive(input,number)

  • 如果输入的已经是一个原始值,则直接返回它,
  • 否则,如果输入的是一个对象,则使用这个对象上面的valueOf()方法。如果valueOf()返回的是一个原始值,则返回这个原始值
  • 否则,调用这个对象上面的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
  • 否则,抛出一个typeError异常

ToPrimitive(input,string)

  • 如果输入的已经是一个原始值,则直接返回它。
  • 否则,如果输入的是一个对象,则使用这个对象上面的toString()方法。如果toString()返回的是一个原始值。则返回这个原始值
  • 否则,调用这个对象上面的vaueOf()方法,如果valueOf方法返回一个原始值,则直接返回
  • 否则,抛出typeError异常

既然第二个参数是可选的,那么如果我们不填写这个参数的话,怎么转换呢?

规则如下:
1、如果对象是Date,则第二个参数是string
2、否则是number

valueOf方法和toString方法解析

JS常见内置对象:Date、Array、Math、Number、Boolean、String、RegExp、Function

1、Number、Boolean、String 这三种构造函数生成的基础值的对象形式,通过valueOf转换后会变成相应的原始值。

比如:

var num = new Number('123')
num.valueOf(); // 123

var str = new String('12df');
str.valueOf(); // '12df'

var bool = new Boolean('fd');
bool.valueOf(); // true

2、Date这种特殊的对象,其原型Date.prototype上内置的valueOf函数是将日期转换为毫秒数的形式的值

var a = new Date();
a.valueOf(); // 1515143895500

3、除此之外返回的都是他们自己本身

var a = new Array();
a.valueOf() === a; // true

var b = new Object({});
b.valueOf() === b; // true

上面说了valueOf函数,下面说说toString函数

1、NumberBoolean、String、Array、Date、RegExp、Function这几种构造函数生成的对象,通过toString转换后会变成相应的字符串的形式,因为这些构造函数上封装了自己的toString方法

Number.prototype.hasOwnProperty('toString'); // true
Boolean.prototype.hasOwnProperty('toString'); // true
String.prototype.hasOwnProperty('toString'); // true
Array.prototype.hasOwnProperty('toString'); // true
Date.prototype.hasOwnProperty('toString'); // true
RegExp.prototype.hasOwnProperty('toString'); // true
Function.prototype.hasOwnProperty('toString'); // true

var num = new Number('123sd');
num.toString(); // 'NaN'

var str = new String('12df');
str.toString(); // '12df'

var bool = new Boolean('fd');
bool.toString(); // 'true'

var arr = new Array(1,2);
arr.toString(); // '1,2'

var d = new Date();
d.toString(); // "Wed Oct 11 2017 08:00:00 GMT+0800 (中国标准时间)"

var func = function () {}
func.toString(); // "function () {}"

除了这些对象及其实例化对象之外,其他的对象返回的都是该对象的类型。都是继承的Object.prototype.toString

var obj = new Object({})
obj.toString() // '[object object]'

Math.toString(); // "[object Math]"

从上面valueOftoString两个函数对对象的转换可以看出为什么对于ToPrimitive(input, PreferredType?),PreferredType没有设定的时候,除了Date类型,PreferredType被设置为String,其它的会设置成Number
因为valueOf函数会将Number、String、Boolean基础类型的对象类型值转换成 基础类型,Date类型转换为毫秒数,其它的返回对象本身,而toString方法会将所有对象转换为字符串。显然对于大部分对象转换,valueOf转换更合理些,因为并没有规定转换类型,应该尽可能保持原有值,而不应该想toString方法一样,一股脑将其转换为字符串。
所以对于没有指定PreferredType类型时,先进行valueOf方法转换更好,故将PreferredType设置为Number类型。
而对于Date类型,其进行valueOf转换为毫秒数的number类型。在进行隐式转换时,没有指定将其转换为number类型时,将其转换为那么大的number类型的值显然没有多大意义。(不管是在+运算符还是==运算符)还不如转换为字符串格式的日期,所以默认Date类型会优先进行toString转换。故有以上的规则:

总结

PreferredType没有设置时,Date类型的对象,PreferredType默认设置为String,其他类型对象PreferredType默认设置为Number

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容