一、先说说String():

String()是全局函数,把对象的值转换为字符串。

语法:String(obj);

任何值(对象)都有String()方法,执行过程是这样的:首先,如果该对象上有toString()方法,则使用该方法(无参数),其次就是没有toString方法,那就是 null 返回 "null",undefined返回"undefined";

【个人理解:任何对象都有String()方法,因为这个全局函数;除了null和undefined,其他对象都有toString()方法】;

二、toString()

语法:obj.toString();

可以将除null和undefined外所有对象转为字符串。是所有内建的 JS 对象的成员,它的操作依赖于对象的类型。

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()方法

【个人理解:既然都是object的子类型,为什么】

接下来的三个例子都是以重写的方式实现了toString()方法:

3.1Array类型:

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

3.2RegExp类型

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

3.3Date类型

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

3.4Number类型也是以重写的方式实现toString()方法的,请看以下例子:

  3.4.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()方法接受的

  3.4.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.4.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"

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

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

三、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上;所以所有对象均可用toString()方法。

【个人理解:但为什么当对象是object的时候,输出的是'[object object]',而其他类型输出的却是类似本身的值?因为其他类型的对象引用的是重写后的toString()方法】

 Object.prototype.toString() 为何能返回这样类型的字符串?
ECMA-262:
1
2
3
4
Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)

上面的规范定义了 Object.prototype.toString 的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于 "[object Array]" 的字符串作为结果([[]]用来表示语言内部用到的、外部不可直接访问的属性,称为 "内部属性")。利用这个方法,再配合 call,我们可以取得任何对象的内部属性 [[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。还是先来看看在 ECMA 标准中 Array 的描述吧:

1
2
new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”.

  所以 Javascript 中判断数组的函数可以这样写:

1
2
3
function isArray(a) {
  Array.isArray ? Array.isArray(a) : Object.prototype.toString.call(a) === '[object Array]';
}

  

四、所以,可以使用Object.prototype上的原生toString()方法判断数据类型,使用方法如下:
 Object.prototype.toString.call(value)

4.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]”

4.2.判断原生引用类型:

4.2.1函数类型

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

4.2.2日期类型

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

4.2.3数组类型

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

4.2.4正则表达式

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

4.2.5自定义类型

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

4.3判断原生JSON对象:

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

注意:Object.prototype.toString()本身是允许被修改的,而我们目前所讨论的关于Object.prototype.toString()这个方法的应用都是假设toString()方法未被修改为前提的。

五、valueOf()和toString()

参考文章1:Javascript中valueOf与toString区别浅析

参开文章2:JavaScript的toString()和valueOf()区别到底是什么

参开文章3:valueOf()函数详解

最新文章

  1. Python 字符串操作及string模块使用
  2. PHP面向对象06_异常处理
  3. HTML <base> 标签 为页面上的所有链接规定默认地址或默认目标
  4. java中的list,set,数组之间的转换
  5. 【Python】我的Python学习笔记【2】【using Python 3】
  6. js中Frame框架的属性获取(1)
  7. Gym 100827G Number Game (博弈)
  8. Android Spinner列表选择框
  9. Linux 安全模块
  10. cheatsheet——mac 上的一款可以显示软件所有快捷键的小工具
  11. 最全DOS的CMD命令,程序员必会
  12. 修改ElementUI源码实践
  13. bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD
  14. 下载合适的tomcat版本
  15. Python-Django 模型层-多表查询-2
  16. 到底什么是哈希Hash?
  17. spoj694
  18. Java第1章笔记
  19. 记一次SQL注入实战
  20. 如何解决iOS6、iOS7 3.5寸和4.0寸屏的适配问题?不要写两个xib文件

热门文章

  1. Centos7.5 mysql5.7.26二进制安装方式
  2. Array 和 ArrayList 、 List 以及 LinkedList 的区别
  3. Linux学习-利用inotify和rsync实现数据的实时同步
  4. tomcat 启动一傘而过问题
  5. GPSMap程序源代码
  6. Android 快速索引(城市列表和联系人)
  7. bzoj 4298 [ONTAK2015]Bajtocja——哈希+启发式合并
  8. 北风设计模式课程---访问者模式(Visitor)
  9. Customizable Route Planning
  10. 服务器上安装搭建node环境