Object.prototypr.toString.call()方法为什么有用

我们判断类型一般会用 typeof,但是一般用于判断未经计算的操作数的类型,无法用于区分数组、正则等

typeof 123;     // 'number'
typeof true;     // 'boolean'
typeof a;         // 'undefined'
typeof true;     // 'boolean'
typeof [1,2,3]; // 'object'
typeof {a:2};   // 'object'
typeof /s/;       // 'object' 
typeof function(){}    // 'function'
typeof null;      // 'object'

小插曲:instanceof一般用于判断继承关系,这里不多做介绍:

var obj={a:1};
obj instanceof Object;    // true

function A(){}
var a=new A();
a instanceof A;    // true

我们除了可以用Array.isArray()来判断是否是数组,还经常能看到这样来判断:

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

我们为什么要这么做判断呢?仔细想一下,这个方法的意思是使用Object这个对象的原型链上的toString方法,为什么不能直接用呢?因为数组本身也有toString方法,我们先来看一下这个方法:

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

toString 是对象上的一个方法,而数字字符串布尔也能执行toString方法,明显和Object上的结果不同,而这些类又是继承于Object,所以应该是它们改写了此方法,下面来验证一下:

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

当我们删除这个方法之后还能继续使用toString,说明它会向上查找,使用了Object上的toString方法。

猜你喜欢

转载自www.cnblogs.com/jingouli/p/12670350.html