js的强转是咱们很容易遇到坑的一个地方 好比 == 会产生颇有意思的事情(使用===仍是最佳实践的) 或者+new Date()一个当前的数字时间戳 这里面都涉及到强转 下面分享下学习强转的过程数组
简单理解强转 强转是指强制将一种类型的对象或者实体转换成另外一种的行为(也就是这种转换的行为不是你主动控制的 区别类型的显示转换) 在发生强转的时候,js老是将一个复杂的对象转化为一个基础的类型值学习
var num = 1111; var b = "" + num; typeof b; //string var c = "10"; var d = +c; typeof d; //number
js在实现强转的时候,会经过调用toString()或者valueOf()返回对象的默认值,这里面涉及到一个抽象操做ToPrimitive 下面是强转的流程this
抽象操做ToPrimitive(input,PreferredType) --> 调用对象内部的[[DefaultValue]] ,[[DefaultValue]]接收PreferredType --> 调用对象的ValueOf()或者toString()方法spa
因此当咱们在建立自定义对象的,但愿在转换基本值的时候,对象能按照咱们的要求去进行一些操做,就须要在对象的原型上实现toString()和valueOf()方法 而且确保他们能按照咱们的意图进行调用prototype
var person = function(name,age) { this.name = name; this.age = age; }; person.prototype.toString = function() { return 'hi' + this.name; }; person.prototype.valueOf = function() { return this.age; }; var test = new person("haha",18); console.log(+test); //18 console.log(test + ''); //18 在转换成字符串的时候和数字的时候 都调用了咱们设置的valueOf方法 并不合理 问题出如今了toPrimitive中
下面是ES6中关于toPrimitive的描述3d
简单的理解就是它会根据hint也就是PreferredType调用[[DefaultValue]]方法,而后调用toString()或者valueOf()方法 为何date对象上能实现可控的toString()和valueOf方法调用呢 code
在规范中对Date对象和Symbol对象进行了处理 因此他能按照咱们的须要去调用toString()或者valueOf()方法 可是在自定义对象上呢 咱们是没法传入hint值的,在没有hint值的状况下会默认hint值为“number”,就会致使上面的例子的出现 若是要达到咱们的要求就须要一些小的技巧对象
插播 valueOf方法 在Object上的方法,返回对象的原始值,在js中许多的内置对象都从新定义了该方法 例如在数组对象上调用valueOf方法会返回数组的实例对象blog
var test = new person("haha",18); console.log(+test); //18 console.log([test] + ''); //hihaha
经过改写上面的例子 将test用数组进行包裹 在toPrimitive方法的时候 会返回数组对象 toPrimitive会继续调用返回基础值,致使对数组每个元素的toString()方法的调用 因此达到了咱们的要求字符串