typeof 对于原始类型(boolean,null,undefined,number,string,symbol),
缺点:除了 null 以及不能区分object 都可以显示正确的类型
原因null 二进制000 而对象在计算中都是以000计算机存储(浏览器bug)
//原始类型存储的都是值,是没有函数可以调用的,比如 undefined.toString() 会报错 typeof 1 // 'number' typeof '1' // 'string' typeof undefined // 'undefined' typeof true // 'boolean' typeof Symbol() // 'symbol' typeof null // 'object' //typeof 对于对象来说不能细分数组、正则、对象中的其他值,因为返回都是Object,除了函数 typeof [] // 'object' typeof {} // 'object' typeof console.log // 'function' typeof Number // 'function'
instanceof 判断一个对象的正确类型,instanceof内部机制是通过原型链来判断的(需要实例)
缺点:1.底层机制:只要当前实例出现在原型链上proto结果都是true
2.不能检测基本类型
let arr = [] console.log(arr instanceof Array)//true console.log(arr instanceof RegExp) //false console.log(arr instanceof Object) //true console.log(1 instanceof Number) //false const Person = function () { } const p1 = new Person() console.log(p1 instanceof Person) // true var str = 'hello world' console.log(str instanceof String)// false var str1 = new String('hello world') console.log(str1 instanceof String)// true
实现instanceof 原型上问题
function instance_of(example, classFunc) { let classFuncPrototype = classFunc.prototype, proto = Object.getPrototypeOf(example) //getPrototypeOf等于Object.__proto__ 因为ie不支持(Object.__proto__) while (true) { if (proto === null) { // Object.prototype.__proto__ =>null 原型顶层null return false } if (proto === classFuncPrototype) { //查找实例中是否存在 return true } proto = Object.getPrototypeOf(proto) } } let arr2 = [] console.log(instance_of(arr2, Array))//true console.log(instance_of(arr2, RegExp))//false console.log(instance_of(arr2, Object))//true
constructor相比instanceof 支持基本类型
缺点:可以随意修改
let arr = [] console.log(arr.constructor === Array)//true console.log(arr.constructor === RegExp) //true console.log(arr.constructor === Object) //false let n = 1 // Number.prototype.constructor = 'A' //可以随便更改 更改后就不正确了 console.log(n.constructor === Number) //true
Object.prototype.toString.call() 标准检测
返回当前实例所属类信息 toString执行this是obj
Object.prototype.toString.call(true);// "[object Boolean]" Object.prototype.toString.call('a');// "[object String]" Object.prototype.toString.call(undefined); // "[object Undefined]" Object.prototype.toString.call(2);// "[object Number]" Object.prototype.toString.call(null); // "[object Null]"
in左侧属性名(字符串)右侧对象或数组,如果自有属性或者继承属性都返回true反之返回false
let a={x:1} console.log('x' in a) //true console.log('y' in a) //false console.log('toString' in a) //true let b=[1,2,3] console.log(0 in b) //true console.log(3 in b) //false
!==判断属性是否是undefined
let d = { x: 1 } console.log(d.x !== undefined) //true console.log(d.y !== undefined) //false console.log(d.toString !== undefined) //true
hasOwnProperty右侧属性名(字符串)左侧对象或数组,如果自有属性返回true,继承过来返回false
let b = { x: 1 } console.log(b.hasOwnProperty('x') ) //true console.log(b.hasOwnProperty('y')) //false console.log(b.hasOwnProperty('toString')) //false
propertyIsEnumerable是hasOwnProperty增加版本,与hasOwnProperty一样,但增加了如果是不可列举也是返回false(不可列举:内置属性,自定义的都是可列举的)
let c ={ x: 1 } c.y=1 console.log(c.propertyIsEnumerable('x') ) //true console.log(c.propertyIsEnumerable('y')) //true console.log(c.propertyIsEnumerable('toString')) //false console.log(Object.prototype.propertyIsEnumerable('toString')) //false