目录
四、Object.prototype.toString.call()
Object.prototype.toString.call(obj)类型检测原理
typeof
在对值类型number
、string
、boolean
、symbol
、 undefined
、 function
的反应是精准的;对象{ }
、数组[ ]
、null
都会返回 object
- console.log(typeof ""); // string
- console.log(typeof 1); // number
- console.log(typeof NaN); // number
- console.log(typeof true); // boolean
- console.log(typeof Symbol(1)) // "symbol"
- console.log(typeof undefined); // undefined
- console.log(typeof function(){}); // function
-
- console.log(typeof null); // object (巨坑...)
- console.log(typeof []); // object
- console.log(typeof {}); //object
instanceof
可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。
用 instanceof
判断一个实例是否属于某种类型
instanceof
运算符只能正确判断引用数据类型,而不能判断基本数据类型- // 检测构造函数B的原型是否有出现在对象A的原型链上。
- A instanceof B
-
- [] instanceof Array // true
- [].__proto__ == Array.prototype // true
-
- console.log([] instanceof Array); // true
- console.log([] instanceof Object); // true
-
- console.log({} instanceof Object); //true
-
- console.log(function(){} instanceof Function); // true
- console.log(function(){} instanceof Object); // true
-
- console.log((new Number(1)) instanceof Number); // true
- console.log((new Number(1)) instanceof Object); // true
- //注意
- console.log(undefined instanceof undefined); // 报错
- console.log(null instanceof null); // 报错
-
constructor 是每个实例对象都拥有的属性
constructor
有两个作用:
constrcutor
对象访问它的构造函数;- function Hello() {}; // 构造函数
- var h = new Hello(); // 实例化对象
-
- console.log(Hello.prototype.constructor == Hello); // true
- console.log(h.constructor == Hello); // true ()
-
- console.log(("1").constructor === String); // true
- console.log((1).constructor === Number); // true
- console.log((NaN).constructor === Number); // true
- console.log((true).constructor === Boolean); // true
- console.log(([]).constructor === Array); // true
- console.log((function () {}).constructor === Function); // true
- console.log(({}).constructor === Object); // true
- console.log((Symbol(1)).constructor === Symbol); // true
-
- console.log((null).constructor === Null); // 报错
- console.log((undefined).constructor === Undefined); // 报错
-
用costructor
来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了:
- function Fn(){};
- Fn.prototype=new Array(); // 改变原型
- var f=new Fn();
-
- console.log(f.constructor===Fn); // false
- console.log(f.constructor===Array); // true
这里声明了一个Fn的构造函数,并且把他的原型指向了Array的原型,所以这种情况下,constructor也显得力不从心了。
使用 Object 对象的原型方法 toString 来判断数据类型:完美精准
的返回各种数据类型
- const a = Object.prototype.toString;
-
- console.log(a.call(1)); // [object Number]
- console.log(a.call("1")); // [object String]
- console.log(a.call(NaN)); // [object Number]
- console.log(a.call(true)); // [object Boolean]
- console.log(a.call(Symbol(1))); // [object Symbol]
- console.log(a.call(null)); // [object Null]
- console.log(a.call(undefined)); // [object Undefined]
- console.log(a.call([])); // [object Array]
- console.log(a.call({})); // [object Object]
- console.log(a.call(function () {})); // [object Function]
-
-
- function Fn(){};
- Fn.prototype=new Array(); // 改变原型
- var f=new Fn();
- console.log(a.call(Fn)); // [object Function]
稍微简单封装下:
- // 定义检测数据类型的功能函数
- function checkedType(target) {
- return Object.prototype.toString.call(target).slice(8, -1);
- }
-
- console.log(checkedType(1)); // Number
- console.log(checkedType("1")); // String
- console.log(checkedType(NaN)); // Number
- console.log(checkedType(true)); // Boolean
- console.log(checkedType(Symbol(1))); // Symbol
- console.log(checkedType(null)); // Null
- console.log(checkedType(undefined)); // Undefined
- console.log(checkedType([])); // Array
- console.log(checkedType({})); // Object
- console.log(checkedType(function () {})); // Function
用Object
原型上的toString
方法作用在传入的obj
的上下文中(通过call
将this
指向obj
)
__proto__
- var arr = []'
- arr.__proto__ === Array.prototype; // true
- var obj = {}'
- obj.__proto__ === Object.prototype; // true
-
- var str = '';
- str.__proto__ === String.prototype; // true
-
- var num = 0;
- num.__proto__ === Number.prototype; // true
通过ES6的Array.isArray()
做判断
Array.isArrray(obj);
通过Array.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(obj)