对Object.prototype.toString.call(obj)的理解

34 篇文章 2 订阅

一,回顾原型链的知识

在这里插入图片描述

1,Object也是个函数,而任何函数都是Function的实例对象。
2,Function可以看作Function自身的实例,所以它的显示原型和隐式原型都指向Function.prototype。
3,任何对象都是Object的instance,因为原型链的顶端都指向Object.prototype。

二,Object.prototype.toString方法的理解

在Object.prototype上有一个toString方法,返回的是值类型。也就是说它可以精准地判断输入值的数据类型。

			function f1(){
				var a=1
			}
			console.log(Object.prototype.toString.call(f1))   //[object Function]
			console.log(Object.prototype.toString.call([]))  //[object Array]
			console.log(Object.prototype.toString.call({}))  //[object Object]
			console.log(Object.prototype.toString.call(null))  //[object Null]
			console.log(Object.prototype.toString.call(undefined))  //[object Undefined]
			console.log(Object.prototype.toString.call(1))   //[object Number]

这里利用call,就是改变this指向,让()里面的来调用Object.prototype.toString方法
至于第一点,为啥讲原型链的知识,那是因为,既然Object的原型对象上有toString方法,JavaScript中,所有类都是Object的实例对象,因此toString()方法应该也被继承了,那为啥又要调用Object.prototype.toString方法,而不直接使用toString方法,让它自己顺着原型链找到这个.toString方法然后调用呢????
实际上,所有类在继承Object的时候,改写了toString()方法。
而只有Object原型上的方法是可以输出数据类型的。因此我们想判断数据类型时,也只能使用原始方法。继而有了此方法:Object.prototype.toString.call(obj)

三,那它们把tostring改写成啥样了?

1,先来看看这个tostring被改写了定义在原型链的什么位置上:

			var arr=[1,2,3]
			console.log(Array.prototype.hasOwnProperty('toString'))  //true
			console.log(Array.hasOwnProperty('toString'))  //false
			console.log(arr.hasOwnProperty('toString'))    //false

这说明,每一种类型都把toString方法改写在了自己的对应的原型对象上(除了Object未改写),于是在构建对应的数据时,才会有:“所有对象都有自己的toString方法” 的说法,也就是说,正常的实例对象(除了obj),顺着它的原型链上查找,都能找到两个toString方法:
一个是定义在Object.prototype上的:用来精准判断数据类型的(只有Object.prototype上有)

另一个是定义在各类别构造函数的原型对象上的:它的作用,下一点讲。
经过验证:只有Function、Array、Boolean、String、Number的prototype上有转化字符的toString()

2,定义在各类别构造函数的原型对象上的toString方法的作用
toString:由名字可以看出此方法是将传入的数据类型转换成字符串输出(null和undefined除外)

var num = 123
num.toString() // '123'
var str = 'hello'
str.toString() // 'hello'
var bool = false
bool.toString() // 'false'
var arr = [1, 2, 3]
arr.toString()  // '1,2,3'
var obj = {lang:'zh'}
obj.toString()  // '[object Object]'
var fn = function(){}
fn.toString()  // 'function(){}'
null.toString()  // Cannot read property 'toString' of null
undefined.toString() // Cannot read property 'toString' of undefined
console.log(Object.toString())  //function Object() { [native code] }
console.log(Array.toString())  //function Array() { [native code] }
console.log(Function.toString())  //function Function() { [native code] }

这里可以有两点说的,

1,obj.toString()  // '[object Object]'
//这个就印证了刚刚的结论,obj的toString方法未被改写,所以它的原型链上只有这一个tostring方法,也就是判断数据类型的方法,也就是所有Object的实例对象的原型链上,只有这么一个判断数据类型的tostring方法
2,
console.log(Object.toString())  //function Object() { [native code] }
console.log(Array.toString())  //function Array() { [native code] }
console.log(Function.toString())  //function Function() { [native code] }
//这几个就可以印证那句话:这些类包括Function自身都是Function的实例对象。所以它们直接使用toString,其实就是使用了改写定义在Function.prototype上面的toString方法!(可参照本文最前面的红线链条理解),而这个tostrings是改写后的,于是打印字符串,因为都是function创建的构造函数,所以都是这个函数

在这里插入图片描述

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值