为什么toString方法可以用来区分数组和对象?

  首先大家都应该知道在javascript中只有是对象都存在toString方法,将调用该方法的值转换为字符串返回,如下:

  

     var arr = [1, 2, 3];
        console.log(arr.toString()); //1,2,3

  但对象的toString方法和其他优点不同,其返回的是类似 ‘[object class]‘的字符串

一、在js中,要想判断一个某个对象是属于哪种内置类型,最靠谱的方法就是通过Object.prototype.toString()方法

   

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

二、Object.prototype.toString()原理:

  ES3中关于Object.prototype.toString()方法的解释

  15.2.4.2 Object.prototype.toString()

  在toString方法被调用时,会执行下面的操作步骤:

    1. 获取this对象的[[Class]]属性的值.

    2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.

    3. 返回第二步的操作结果Result(2).

 

  [[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.[[class]]为一个表明该对象类型的内部属性,其值类型为字符串。

所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).

也就是说,把Object.prototype.toString方法返回的字符串,去掉前面固定的"[object "和后面固定的"]",就是内部属性[[class]]的值,也就达到了判断对象类型的目的.jQuery中的工具方法$.type(),就是干这个的.

在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number","Object", "RegExp", "String".

 

es5中关于Object.prototype.toString()方法的解释

ES5.1中,除了规范写的更详细一些以外,Object.prototype.toString方法和[[class]]内部属性的定义上也有一些变化,Object.prototype.toString方法的规范如下:

15.2.4.2 Object.prototype.toString ( )

toString方法被调用时,会执行下面的操作步骤:

  1. 如果this的值为undefined,则返回"[object Undefined]".
  2. 如果this的值为null,则返回"[object Null]".
  3. O成为调用ToObject(this)的结果.
  4. class成为O的内部属性[[Class]]的值.
  5. 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.

可以看出,比ES3多了1,2,3步.第1,2步属于新规则,比较特殊,因为"Undefined"和"Null"并不属于[[class]]属性的值,需要注意的是,这里和严格模式无关(大部分函数在严格模式下,this的值才会保持undefined或null,非严格模式下会自动成为全局对象).第3步并不算是新规则,因为在ES3的引擎中,也都会在这一步将三种原始值类型转换成对应的包装对象,只是规范中没写出来.ES5中,[[Class]]属性的解释更加详细:

所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]内部属性是引擎内部用来判断一个对象属于哪种类型的值的.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).

和ES3对比一下,第一个差别就是[[class]]内部属性的值多了两种,成了12种,一种是arguments对象的[[class]]成了"Arguments",而不是以前的"Object",还有就是多个了全局对象JSON,它的[[class]]值为"JSON".第二个差别就是,宿主对象的[[class]]内部属性的值,不能和这12种值冲突,不过在支持ES3的浏览器中,貌似也没有发现哪些宿主对象故意使用那10个值.

参考文章:http://www.cnblogs.com/ziyunfei/archive/2012/11/05/2754156.html

时间: 2024-11-08 19:07:54

为什么toString方法可以用来区分数组和对象?的相关文章

java 数组的 toString 方法和 equals 方法以及 java.lang.Object 对象的 toString 方法和 equals 方法

1 public class Test { 2 public static void main(String[] args) { 3 int[] a = {1, 2, 4, 6}; 4 int[] b = a; 5 int[] c = {1, 2, 4, 6}; 6 7 //下面这个方法打印的是a数组的引用地址 8 System.out.println(a.toString()); 9 //下面这个方法比较的是两个数组的引用是否相等 10 System.out.println("a.equals

[Effective JavaScript 笔记]第58条:区分数组对象和类数组对象

示例 设想有两个不同类的API.第一个是位向量:有序的位集合 var bits=new BitVector(); bits.enable(4); bits.enable([1,3,8,17]); bits.bitAt(4);//1 bits.bitAt(8);//1 bits.bitAt(9);//0 enable方法被重载了,可以传入一个索引或索引的数组.第二个类的API是字符串集合:无序的字符串集合 var set=new StringSet(); set.add('Hamlet'); se

Java对象toString()方法

对象的字符串表示以可读格式包含有关对象状态的信息.Object类的toString()方法表示字符串中类的对象.Object类提供了toString()方法的默认实现. 它返回一个以下格式的字符串: 1 <fully qualified class name>@<hash code of object in hexadecimal> 示例 考虑下面的代码及其输出.如是亲自执行代码可能会得到不同的输出. 1 2 3 4 5 6 7 public class Main{   publi

javascript Array对象toString()方法

toString() 方法可把数组转换为字符串,并返回结果. 语法: arrayObject.toString() 返回arrayObject的字符串表示.返回值与没有参数的join()方法返回的字符串相同.数组中的元素之间用逗号分隔. 当数组用于字符串环境时,JavaScript 会调用这一方法将数组自动转换成字符串.但是在某些情况下,需要显式地调用该方法. 例子: <script type="text/javascript"> var arr = new Array(3

从toString()方法到Object.prototype.toString.call()方法

一.toString方法和Object.prototype.toSting.call()的区别 var arr=[1,2]; 直接对一个数组调用toString()方法, console.log(arr.toString());    //输出1,2 现在通过call方法指定arr数组为Object.prototype对象中的toString方法的上下文. console.log(Object.prototype.toString.call(arr));    //输出[Object Array

JavaScript中valueOf函数与toString方法的使用

所有JS数据类型都拥有valueOf和toString这两个方法,null除外. JavaScript中valueOf函数方法是返回指定对象的原始值. 使用方法: object.valueOf( ). object是必选参数,是任意固有 JavaScrip对象. JavaScript 的 valueOf() 方法 valueOf() 方法可返回 Boolean 对象的原始值. 用法booleanObject.valueOf(),返回值为booleanObject 的原始布尔值.如果调用该方法的对

判断一个变量类型是数组还是对象

因为无论是数组还是对象,对于typeof的操作返回值都为object,所以就有了区分数组类型和对象类型的需要: 方一:通过length属性:一般情况下对象没有length属性值,其值为undefiend,而数组的length值为number类型 缺点:非常不实用,当对象的属性存在length,且其值为number(比如类数组),则该方法失效,不建议使用,看看即可. *方二:通过instanceof来判断区分 var arr = [1, 2, 3]; var obj = { name: 'lyl'

为何重写toString方法后会使哈希码能够打印出来

首先还是推荐lz看源代码 简单的讲之所以调用了toString()方法,不是什么编译器默认的,而是因为lz你调用的是out.print()方法仔细看源代码,在PringStream类中,print方法是这样写的 public void print(Object obj) { write(String.valueOf(obj)); }此时调用了String的静态方法valueof这个方法是这样的 public static String valueOf(Object obj) { return (

equals hashcode toString 方法的使用

package com.wu.toString; import java.util.Date; import java.util.GregorianCalendar; /** * * @author wuyong * @email [email protected] * @date2016年9月1日下午4:39:09 * 雇员类 */ class Employee { private String name; private double salary;//薪水 private Date hir