zoukankan      html  css  js  c++  java
  • 从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]
    错误理解:按照arr是Object对象的子集,应该toString()方法会继承下来,所以两个得到的结果应该是一样的,但是现实是残酷的。
    原因:Object.prototype的toString方法确实被继承下来了,但是很多东西总不会一层不变,作为儿子的数组重写了toString方法,所以直接调用数组对象上面的toString方法调用到的实际是重写后的方法,并不是Object.prototype中的toString方法。Array,Function等类型作为Object的实例,都重写了toString方法,不同的对象类型调用toString()方法时,根据原型链的知识,调用的是重写之后的toString方法(函数返回的是函数体内的字符串,Array返回的是元素组成的字符串)
    应用场景:Object.prototype对象上的toString方法可以用来判断数据类型
    例如:Object.prototype.toString.call(arr);   输出:[Object Array] 判断是否是数组
     
    例子2:
    var arr=[1,2,3];
    console.log(Array.prototype hasOwnPrototype('toString'))    //true
    console.log(arr.toString())   //1,2,3
    delete Array.prototype.toString;   //delete操作符可以删除实例属性
    console.log(Array.prototype hasOwnPrototype('toString'))    //false
    console.log(arr.toString())   //[object Array];
    删除了Array的toString方法后,同样采用arr.toString()方法调用,不再屏蔽Object原型方法的实例方法,arr最后调用了Object的toString方法。
     
    而重写后的toString方法可以把对象转换成字符串,还可以把数值转换成不同进制的数字
    [1,2].toString();//1,2 得到字符串
    (10).toString(2)  //十进制转二进制,输出1010,如果10.toString(2)会报错,因为js会认为.是数字的小数点而不是调用符号。
    二、为什么用Object.prototype.toString.call(obj)检测对象类型?
    第一种:用typeof判断
    我们知道typeof可以检测数据类型,对变量或值调用typeof运算符将返回下列值之一:
    undefined->Undefined
    boolean->Boolean
    number->Number
    string->String
    object->是引用类型或null类型。
    function->function函数
    typeof检测引用类型或null是不能准确区分arr json等引用类型的。
    那我们还知道一种检测方式instanceof,来检测某个对象是不是另一个对爱心那个的实例
    第二种:用instanceof判断
    instanceof运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。
    主要用来检测引用类型,判断Array和RegExp,无法准确判断Function,因为函数,日期,正则都是对象的特殊形式,所以用instanceof判断Object,都是true.
    console.log([] instanceof Array)   //true
    console.log({} instanceof Object)   //true
    console.log(/d/ instanceof RegExp)   //true
    console.log(function(){} instanceof Object)  //true
    console.log(function(){} instanceof Function)   //true
    console.log([] instanceof Object)   //true   判断错误
    console.log(function(){} instanceof Object)   //true   判断错误
    console.log('' instanceof String)   //false
    console.log(1 instanceof Number)   //false
     
     
    var a=new Array();
    alert(a instanceof Array);
    同时alert(a instanceof Object)也会返回true,因为Array是object的子类。
    function test(){}
    var a=new test();
    alert(a instanceof test);会返回true.
    alert(a==b)  //false;
     
    另外,更重要的一点是instanceof可以在继承关系中用来判断一个实例是否属于他的父类型。
    function Foo(){}
    Foo.prototype=new Aoo()    //js原型继承
    var foo= new Foo();
    console.log(foo instanceof Foo)   //true
    console.log(foo.instanceof Aoo)   //true
    上面代码中是判断了一层继承关系的父类,在多层继承关系中,isntanceof运算符同样适用。
     
    //定义构造函数
    function C(){}
    function D(){}
     var o=new C();
    o instanceof C   //true   
    o instanceof D   //false 因为D.prototype不在o的原型链上
    o instanceof Object   //true   因为Object.prototype.isPrototypeOf(o)  返回true
    C.prototype instanceof Object   //true 同上
     
    C.prototype={}
    var o2=new C();
    o2 instanceof C   //true
    o instanceof C    //false    C。prototype指向了一个空对象,这个空对象不在o的原型链上。
    D.prototype =new C();       //继承
    var o3=new D();
    o3 instanceof D   //true
    o3 isntanceof C   //true
    谈到instanceof 我们要多插入一个问题,就是function的arguments,我们大家也许认为arguments是一个Array,但如果用instanceof去测试回发现arguments不是一个Array对象,尽管看起来很像。
     
    第三种:Object.prototype.toString
    这是对象的一个原生扩展函数,用来精确区分数据类型
    var type=Object.prototype.toString
    console.log(type.call(''))    //object String
    console.log(type.call([]))    //object Array
    console.log(type.call({}))   //object Object
    console.log(type.call(false))   //object Boolean
    console.log(type.call(null))    //object Null
    console.log(type.call(undefined))   //object Undefined
    console.log(type.call(function(){}))   //object Function
     
     
     
     
     
     
     
     
  • 相关阅读:
    destoon手机端mobileurl函数增加城市分类参数
    jCarousel,jQuery下的滚动切换传送插件
    jQuery plugin : bgStretcher 背景图片切换效果插件
    jquery图片切换插件jquery.cycle.js参数详解
    destoon 后台管理左侧新增菜单项
    destoon 列表页面增加手动选择排序方式
    jQuery 淡入淡出有png图的时候 ie8下有黑色边框
    java中Array和ArrayList区别
    趣味理解ADO.NET对象模型
    两个datatable的比较
  • 原文地址:https://www.cnblogs.com/learnings/p/9260081.html
Copyright © 2011-2022 走看看