你不知道的toString方法

一、toString()是一个怎样的方法?它是能将某一个值转化为字符串的方法。然而它是如何将一个值从一种类型转化为字符串类型的呢?

通过下面几个例子,我们便能获得答案:

1.将boolean类型的值转化为string类型:

console.log(true.toString());//"true"
console.log(false.toString());//"false"

2.将string类型按其字面量形式输出:

var str = "test123y";
console.log(str.toString());//"test123y"

3.将Object类型转化成string类型(JavaScript原生的Array类型、Date类型、RegExp类型以及Number、Boolean、String这些包装类型都是Object的子类型):
自定义Object类型(没有重新定义toString方法):

var obj = {name:"Tom", age:18};
console.log(obj.toString());//"[object Object]"此时调用的是从Object继承来的原始的toString()方法

接下来的三个例子都是以重写的方式实现了toString()方法;
1.Array类型:

var arr = ["tom",12,"rose",18];
console.log(arr.toString());//"tom,12,rose,18"

2.RegExp类型

var patten = new RegExp("\\[hbc\\]at", "gi");
console.log(patten.toString());//"/\[hbc\]at/gi"

3.Date类型

var date = new Date(2014,02,26);//注意这种格式创建的日期,其月份是3月
console.log(date.toString());//"Wed Mar 26 2014 00:00:00 GMT+0800"输出格式因浏览器不同而不同,此为firefox的输出格式;

4.Number类型也是以重写的方式实现toString()方法的,请看以下例子:
(1)它可以接受一个整数参数,并将调用这个方法的数值转化成相应进制的字符串:

var num = 16;
console.log(num.toString(2));//10000 二进制
console.log(num.toString(8));//20 八进制
console.log(num.toString(16));//10 十六进制
console.log(num.toString(5));//31 虽然没有五进制,但是这样传参是可以被toString()方法接受的

(2)再看下面的代码:

console.log(1.toString());//这种写法会报错语法错误,但是下面的写法都是合法的;
console.log((1).toString());//"1"
console.log(typeof (1).toString());//string
console.log(1..toString());//"1"
console.log(typeof (1).toString());//string
console.log(1.2.toString());//"1"
console.log(typeof (1).toString());//string

这是因为javascript引擎在解释代码时对于“1.toString()”认为“.”是浮点符号,但因小数点后面的字符是非法的,所以报语法错误;
而后面的“1..toString()和1.2.toStirng()”写法,javascript引擎认为第一个“.”小数点,的二个为属性访问语法,所以都能正确解释执行;
对于“(1).toStirng()”的写法,用“()”排除了“.”被视为小数点的语法解释,所以这种写法能够被解释执行;
(3)纯小数的小数点后面有连续6或6个以上的“0”时,小数将用e表示法进行输出;

var num = 0.000006;//小数点后面有5个“0”
console.log(num.toString());//"0.000006"
var num = 0.0000006;//小数点后面有6个“0”
console.log(num.toString());//"6e-7"

(4)浮点数整数部分的位数大于21时,输出时采用e表示法;

var num = 1234567890123456789012;
console.log(num.toString());//"1.2345678901234568e+21"

看到这里大家难免会有些疑问,这些基本的数据类型的值都是常量,而常量是没有方法的,为什么能够调用方法呢?答案是这样的,五种基本类型除了null、undefined以外都有与之对应的特殊的引用类型——包装类型。当代码被解释执行时,底层会对基本类型做一个类型转换,即将基本类型转换成引用类型,这样就可以调用相应引用类型有权访问到的方法。
二、toString()方法定义在何处?
运行以下代码:

var pro = Object.prototype;
var pr = pro.__proto__;//ie11之前版本不支持该属性
console.log(typeof pro);//"object"
console.log(String(pro));//"[object Object]"
console.log(pro.hasOwnProperty("toString"));//true
console.log(typeof pr);//"object"
console.log(String(pr));//"null"
console.log(pr.hasOwnProperty("toString"));//报错

由此可知,toString()定义在Object.prototype上;
三、使用Object.prototype上的原生toString()方法判断数据类型,使用方法如下:

Object.prototype.toString.call(value)

1.判断基本类型:

Object.prototype.toString.call(null);//”[object Null]”
Object.prototype.toString.call(undefined);//”[object Undefined]”
Object.prototype.toString.call(“abc”);//”[object String]”
Object.prototype.toString.call(123);//”[object Number]”
Object.prototype.toString.call(true);//”[object Boolean]”

2.判断原生引用类型:
函数类型

Function fn(){console.log(“test”);}
Object.prototype.toString.call(fn);//”[object Function]”

日期类型

var date = new Date();
Object.prototype.toString.call(date);//”[object Date]”

数组类型

var arr = [1,2,3];
Object.prototype.toString.call(arr);//”[object Array]”

正则表达式

var reg = /[hbc]at/gi;
Object.prototype.toString.call(arr);//”[object Array]”

自定义类型

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(arr); //”[object Object]”

很明显这种方法不能准确判断person是Person类的实例,而只能用instanceof 操作符来进行判断,如下所示:

console.log(person instanceof Person);//输出结果为true

3.判断原生JSON对象:

var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON);
console.log(isNativeJSON);//输出结果为”[object JSON]”说明JSON是原生的,否则不是;

注意:Object.prototype.toString()本身是允许被修改的,而我们目前所讨论的关于Object.prototype.toString()这个方法的应用都是假设toString()方法未被修改为前提的。
本文所讨论内容多参考于《JavaScrip高级编程》第三版,另因个人水平有限,如有描述不当之处还请高手指正。

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

推荐阅读更多精彩内容

  • toStirng()与Object.prototype.toString.call()方法浅谈 一、toStrin...
    Michael_林阅读 1,035评论 1 4
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 09年结婚,转眼间就到了2016年,马上要迎来7年结婚纪念日了。结婚这么多年,终于找到了适合我们夫妻的一些相处...
    花不言阅读 629评论 0 1
  • 今天的月亮很圆很亮,照得我不敢直视,犹如黑暗中的妖怪,见到月光会死。我这次做的好绝,把所有的关系都割断掉,因为,我...
    罅02阅读 149评论 0 0
  • 咪蒙公众号 2017.03.27 原标题 "慢慢爱上你,慢慢慢慢慢慢忘记你" 我来改标题 ①你们男人都这么快,这样...
    永利哥阅读 229评论 0 2