一、typeof
1. typeof 优点?缺点?
优点:能够快速区分基本数据类型
缺点:不能将Object、Array和Null区分,都返回object
2. typeof 作用?
区分数据类型,可以返回7种数据类型:number、string、boolean、undefined、object、function
,以及 ES6
新增的 symbol
3. typeof 能正确区分数据类型吗?
不能。对于原始类型,除 null
都可以正确判断;对于引用类型,除 function
外,都会返回 "object"
4. typeof 注意事项
typeof 未定义的变量不会报错,返回 "undefiend"
typeof(null) -> "object": 遗留已久的 bug
typeof无法区别数组与普通对象: typeof([]) -> "object"
typeof(NaN) -> "number"
5. typeof为什么对null错误的显示
这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object
6. typeof('abc')和 typeof 'abc'都是 string, 那么 typeof 是操作符还是函数?
答案:typeof 是操作符
原因:
typeof 的返回值之一为'function',如果 typeof 为 function,那么 typeof(typeof) 会返回'function',但是经测试,上述代码浏览器会抛出错误。因此可以证明 typeof 并非函数。
既然 typeof 不是函数,那 typeof 后面的括号的作用是?
括号的作用是进行分组而非函数的调用。—— 《javascript 高级程序设计》
二、实现一个 typeof
function _typeof(value){ return Object.prototype.toString.call(value).slice(8,-1).toLowerCase(); }
三、instanceof原理
优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断
① instanceof 判断对象的原型链上是否存在构造函数的原型。只能判断引用类型。
② instanceof 常用来判断 A 是否为 B 的实例
// A是B的实例,返回true,否则返回false // 判断A的原型链上是否有B的原型 A instaceof B
四、typeof 与 instanceof 的区别
typeof与instanceof都是判断数据类型的方法,区别如下:
typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
而 typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断
五、模拟实现一个 instanceof
思想:沿原型链往上查找
instance_of (Case, Constructor) { console.log('Case:', typeof Case, 'Constructor1:', typeof Constructor); // 基本数据类型 返回false if ((typeof (Case) != 'object' && typeof (Case) != 'function') || Case == 'null') return false let CaseProto = Object.getPrototypeOf(Case); console.log('CaseProto:', CaseProto); console.log('Constructor:', Constructor.prototype); while (true) { // 查到原型链顶端,仍未查到,返回false if (CaseProto == null) return false; // 找到相同类型 if (CaseProto == Constructor.prototype) return true; CaseProto = Object.getPrototypeOf(CaseProto) } },
function A () { } function B () { } const C = new A(); const D = new B(); console.log(this.instance_of(C, A)); // true console.log(this.instance_of(D, B)); // true console.log(this.instance_of(C, Array)); // false
六、通用监测数据类型:Object.prototype.toString.call()
优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用
Object.prototype.toString.call(()=>{}) // [object Function] Object.prototype.toString.call({}) // [object Object] Object.prototype.toString.call([]) // [object Array] Object.prototype.toString.call('') // [object String] Object.prototype.toString.call(22) // [object Number] Object.prototype.toString.call(undefined) // [object undefined] Object.prototype.toString.call(null) // [object null] Object.prototype.toString.call(new Date) // [object Date] Object.prototype.toString.call(Math) // [object Math] Object.prototype.toString.call(window) // [object Window]