关于JavaScript中的类型判断,我想大部分JavaScripter 都很清楚 typeof 和 instanceof,却很少有人知道 constructor,以及constructor与前面二者的关系
typeof
console.log(typeof 1); //number console.log(typeof "宋远溪"); // string console.log(typeof true); // boolean console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof Symbol(1)); //symbol console.log(typeof null);//object console.log(typeof undefined); // undefined console.log(typeof BigInt(1)); //bigint, ES10推出的BigInt是一个内置对象,它提供了表示大于最大安全整数之外的方法, bigint 通常用于计算最大安全整数之外的数值
如你所见,typeof只能进行最基本的类型判断;那我们如果想知道一个变量是对象或者是数组怎么办?接下来
instanceof
console.log ({} instanceof Object); // true console.log ([] instanceof Array); // true function Something () {} var sth = new Something(); console.log(sth instanceof Something); // true
可以看到 instanceof 能区分出数据的类型,以及该数据是由谁创建的,但是,instanceof 就真的万无一失吗?继续往下
function Something () {} function Anything() {} Something.prototype = new Anything(); var sth = new Something(); console.log(sth instanceof Something);//true console.log(sth instanceof Anything);//true
为什么会这样?
因为instanceof 会检查 Anything 是否 存在与 sth 的原型链上,如果存在,则返回True,这么说的话,下面的也是成立的
console.log(sth instanceof Object); //true
constructor
function Something() {} function Anything() {} var template = new Anything(); template.constructor = Something; Object.defineProperty(template,'constructor',{ enumerable:false, writable:false, }); Something.prototype = template; const sth = new Something(); console.log(sth.constructor === Something);//true console.log(sth.constructor === Anything);//false console.log(Object.keys(sth)); // [],因为constructor属于内置属性,所以我们配置不可枚举,不可重写;
sth.constructor 其实就是 sth.__proto__.constructor,因为constructor属性存在于原型链上,所以我们可以直接简写;这样就能实现精确1对1比对了