Object.prototype.toString.call的理解
首先Object.prototype.toString.call(foo)的作用用来检验参数foo的数据类型。接下来一层一层的分析其原理。
toString()方法
js中包装类Number、String、Boolean、Array、Object和Function都是继承自Object,同时也继承了Object的toString方法。但是这些包装类又分别对toString方法进行了重写,使得输出各有不同,而且同一封装类型如String在其内容不同时会返回不同的值。显然这样的返回值不能作为判断不同类型的依据
var number = 123456
console.log(number.toString()) // '123456'
var bool = false
console.log(bool.toString()) // 'false'
var str = 'abc'
console.log(str.toString()) // 'abc'
var str1 = 'abcdefg'
console.log(str1.toString()) // 'abcdefg'
var array = [1, 2, 3]
console.log(array.toString()) // '1,2,3'
var obj = { foo: 'foo'}
console.log(obj.toString()) // '[object Object]'
var fun = function f() {}
console.log(fun.toString()) // 'function f() {}'
我们先试着让不同类型的数据能调用原始的toString方法
delete Number.prototype.toString
delete Boolean.prototype.toString
delete String.prototype.toString
delete Array.prototype.toString
delete Function.prototype.toString
var number = 123456
console.log(number.toString()) // '[object Number]'
var bool = false
console.log(bool.toString()) // '[object Boolean]'
var str = 'abc'
console.log(str.toString()) // '[object String]'
var array = [1, 2, 3]
console.log(array.toString()) // '[object Array]'
var obj = { foo: 'foo'}
console.log(obj.toString()) // '[object Object]'
var fun = function f() {}
console.log(fun.toString()) // '[object Function]'
可以看到在删除的封装类的toString方法后,调用时会去原型链不断向上,最终调用了原始Object.prototype.toString方法,最终返回值终于有了统一和区别。但是这种删除的封装类的方法会破坏封装类的toString方法,同时影响其它需要用到toString的模块。
于是我们的需求是在不改变封装类的方法时,仍然能使封装类调用原始的toString方法
调用call()方法,使封装类调用原始的toString方法
call方法由于可改变当前调用方法的this作用域。在Object.prototype.toString.call(foo)语句中,call使得
toString()方法里的this指向foo(此处的foo可以为任意数据类型)。
虽说方法内容依然是原始的toString方法,但是调用对象相当于已经由Object.prototype转为了foo,这就完成了foo直接调用原始的toString。
var number = 123456
console.log(Object.prototype.toString.call(number)) // '[object Number]'
var bool = false
console.log(Object.prototype.toString.call(bool)) // '[object Boolean]'
var str = 'abc'
console.log(Object.prototype.toString.call(str)) // '[object String]'
var array = [1, 2, 3]
console.log(Object.prototype.toString.call(array)) // '[object Array]'
var obj = { foo: 'foo'}
console.log(Object.prototype.toString.call(obj)) // '[object Object]'
var fun = function f() {}
console.log(Object.prototype.toString.call(fun)) // '[object Function]'