js 强转规范解读

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  下面是强转的流程

抽象操作ToPrimitive(input,PreferredType)   -->  调用对象内部的[[DefaultValue]] ,[[DefaultValue]]接收PreferredType  --> 调用对象的ValueOf()或者toString()方法

所以当我们在创建自定义对象的,希望在转换基本值的时候,对象能按照我们的要求去进行一些操作,就需要在对象的原型上实现toString()和valueOf()方法 并且确保他们能按照我们的意图进行调用

        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的描述

 

简单的理解就是它会根据hint也就是PreferredType调用[[DefaultValue]]方法,然后调用toString()或者valueOf()方法  为什么date对象上能实现可控的toString()和valueOf方法调用呢  

在规范中对Date对象和Symbol对象进行了处理 所以他能按照我们的需要去调用toString()或者valueOf()方法 但是在自定义对象上呢 我们是无法传入hint值的,在没有hint值的情况下会默认hint值为“number”,就会导致上面的例子的出现 如果要达到我们的要求就需要一些小的技巧

插播  valueOf方法  在Object上的方法,返回对象的原始值,在js中许多的内置对象都重新定义了该方法 例如在数组对象上调用valueOf方法会返回数组的实例对象

        var test = new person("haha",18);
        console.log(+test);  //18
        console.log([test] + ''); //hihaha

通过改写上面的例子 将test用数组进行包裹 在toPrimitive方法的时候 会返回数组对象  toPrimitive会继续调用返回基础值,导致对数组每一个元素的toString()方法的调用 所以达到了我们的要求

 

posted on 2016-10-23 11:32  icantunderstand  阅读(302)  评论(0编辑  收藏  举报

导航