说说toString

先从一个小问题说起:

  请你设计一个方法,用来将多维数组拍平。比如[1,2,3,[4,5,[6,7,8]]]  ==> [1,2,3,4,5,6,7,8]

看到这,估计很多人开始考虑各种迭代,各种遍历之类的方法了,诚然,通过遍历可以实现,然而这种实现方法既不优雅,也太麻烦。今天看一个简单的方法:

function flat(arr) {
     return (arr + '').split(',').map(function(e,i) {
         return +e;
     });
}

flat([1,2,3,[4,5,[6,7,8]]]);   // [1,2,3,4,5,6,7,8]

恩,代码的确很短,但今天不是为代码太短而高兴的,我们要弄清楚到底发生了什么。

今天要探讨的点在这里:

arr + ''

一个数组 + 一个空字符串,这到底是什么呢?

众所周知,arr是一个对象,我们直接打印一个对象,会发生什么呢?

看下面一段代码:

var test = {
    a : 'A',
    b : 'B'
};

alert(test);  //[object Object]

我们看到,对象以一种奇怪的方式被打印出来了。那么对象为什么会以这种格式打印呢,我们如果想控制打印样式该怎么办呢?继续往下看

Object.prototype.toString = function(){
    return "本来该打印对象的,结果打印出了我";
}

var test = {
    a : 'A',
    b : 'B'
};

alert(test);   //本来该打印对象的,结果打印出了我

看到这里就应该明白了,我们打印对象时,实际上调用了Object.prototype对象的toString方法,因为所有的对象的原型链顶端都是Object.prototype,即任何对象都可以使用toString方法,所以,我们可以打印任何对象。

Object.prototype.toString默认使用[object ***]的方式打印对象,具体的打印结果如下:

var toString = Object.prototype.toString();

alert(toString.call(1));                    //    [object Number]
alert(toString.call('1'));                  //    [object String]
alert(toString.call(new Date()));        //     [object Date]
alert(toString.call(new RegExp()))       //    [object RegExp]
alert(toString.call(true));                //     [object Boolean]
alert(toString.call([]));                  //     [object Array]
alert(toString.call({}));                 //      [object Object]
alert(toString.call(null));               //      [object Null]
alert(toString.call(undefined));        //       [object Undefined]

这种方法可以准确的判断一个数据的类型,当typeof无法精确判断时可以采用这种方法判断;

另外,我们看到,这里toString是通过call来调用的,为什么呢?

因为有些对象复写了toString方法

还是看代码:

alert(["ni","hao","world"].toString());  //"ni,hao,world"
已重写
Array会对每一个元素调用toString方法然后再调用join方法,最终返回一个字符串

alert((22).toString())   // 22
已重写
Number.toString([radix])  radix代表进制,从2到36

alert((function(){}).toString());  //function(){}
已重写
返回一个表示当前函数源代码的字符串

alert((true).toString())   //true
已重写
返回一个指定布尔对象的字符串形式

alert((new RegExp('a+b+c')).toString())   //  /a+b+c/
已重写
返回一个表示该正则表达式的字符串

alert((new Date()).toString())   //Mon Jul 18 2016 18:59:06 GMT+0800 (CST)
已重写
返回一个字符串,表示该Date对象

 

说了这么多,现在回头看看 arr + '',这就一目了然了,arr + ''会主动调用toString方法,将该数组转成一个由元素组成的字符串

好了,说了这么多,toString能说的基本上也说过了,如果还有什么遗漏,后期再补上

posted @ 2016-07-18 19:05  SudoKillMe  阅读(215)  评论(0编辑  收藏  举报