看这篇博客前确保你了解了原型与原型链的知识,原理大多涉及到了原型与原型链的知识。
可看我这篇博客了解原型与原型链
js高级之原型与原型链
1.Object.prototype.toString.call/apply()
结论
首先抛出结论:带着结论我们来理解这个方法
object.prototype.toString.call()方法其实是利用 Object.prototype.toString()方法可以返回“[obejct 对象构造函数名]” 的原理来确定数据类型,并且js中所有对象都是Object的实例,可以使用call/apply 调用 Object.prototype原型对象的tostring()方法
Object.prototype.toString.call/apply() 可以判断任何数据类型
不存在浏览器兼容问题
判断基本数据类型
console.log(Object.prototype.toString.call('d')) // [object String]
console.log(Object.prototype.toString.call(8)) // [object Number]
console.log(Object.prototype.toString.call(false)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call(Symbol(1))) // [object Symbol]
判断引用数据类型
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(function a(){})) // [object Function]
console.log(Object.prototype.toString.call(/a+/)) // [object RegExp]
Object.prototype.toString.call/apply() 原理
Object.prototype代表Object的原型对象,里面存储了很多方法例如:toString,length,等等而toString方法返回的类型是“[obejct 对象构造函数名]”,上面事例中可以看到假如我判断一个对象
console.log(Object.prototype.toString.call({})) // [object Object]
返回类型第一个是object ,第二个是我传入的对象的构造函数名,这里传入了一个实例对象,通过原型链可知对象的实例对象指向的构造函数名为Object,所以输出了 [object Object],而所有的js中所有对象都是Object的实例所以都可以通过原型链访问到这个方法。所以就可以判断数据类型了。
2.typeof
最常用的但有缺陷
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof []); // object
console.log(typeof function(){}); // function
console.log(typeof {}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object
其中数组、对象、null都会被判断为object,其他判断都正确。
3.instanceof
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
可以看到,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。instanceof 运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
那为什么不能判断基本数据类型呢?
首先我们知道instanceof的原理是根据该实例对象的构造函数是否等于后面一个构造函数,
而既然不能判断基本数据类型说明 2 ,‘str’,等基本数据类型并没有被实例化成对象。
代码为证:
console.log(new Number(2) instanceof Number);
console.log(new Boolean(true) instanceof Boolean);
console.log(new String('str') instanceof String);
可以看到当我使用new实例化基本数据类型时判断为true,进一步说明2 ,‘str’,等基本数据类型在没有new实例化成对象都并不是实例对象。
4.constructor
原理很简单:对象通过constructor 来访问它的构造函数
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
constructor有两个作用,一是判断数据的类型,
二是对象实例通过 constrcutor 对象访问它的构造函数(原型链知识)。
需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了:
创作不易如有错误欢迎指出