JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

typeof

对一个值使用typeof操作符可能返回:

undefined、string、number、boolean、symbol、object(对象或null)、function

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object  []数组的数据类型在 typeof 中被解释为object
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object    null 的数据类型被 typeof 解释为 object

typeof 对于基本类型,除了null都可以显示正确的类型;对于对象,除了函数都会显示object。

对于null来说,虽然它是基本类型,但是会显示object,这是一个存在了很久的bug。

因为在js的最初版本中,使用的是32位系统,为了性能考虑使用低位存储了变量的类型信息,000开头代表是对象,然而null表示为全零,所以将它错误的判断为object。虽然现在的内部类型 判断代码已经改变了,但是对于这个bug却是一直流传下来。

instanceof

只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。

instanceof可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找得类型的prototype

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    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
function Person(name, age) {
    this.name = name;
    this.age = age;
}
function Dog(name, age) {
    this.name = name;
    this.age = age;
}
var p = new Person('zs', 18);
var d = new Dog('小花', 8);

console.log(p instanceof Person);       // true
console.log(d instanceof Person);       // true
console.log(p instanceof Object);		// false

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

用costructor来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了。

function Person(name, age) {
    this.name = name;
    this.age = age;
}

var p = new Person('csm', 21);

console.log(p.constructor.name); 	// Person

// 改变原型
Person.prototype = {
    name: 'zs',
    age: 18
};

var p1 = new Person('csm', 21);

console.log(p1.constructor.name); 	// Object

因此,当要修改对象的proptotype时,一定要设置constructor指向其构造函数

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype = {
	constructor: Person,
    name: 'zs',
    age: 18
};
var p = new Person('csm', 21);
console.log(p.constructor.name); 	// Person

object.prototype.toString.call()

console.log(Object.prototype.toString.call(2));    			// [object Number]
console.log(Object.prototype.toString.call(true));			// [object Boolean]
console.log(Object.prototype.toString.call('str'));			// [object String]
console.log(Object.prototype.toString.call([]));			// [object Array]
console.log(Object.prototype.toString.call(function(){}));	// [object Function]
console.log(Object.prototype.toString.call({}));			// [object Object]
console.log(Object.prototype.toString.call(undefined));		// [object Undefined]
console.log(Object.prototype.toString.call(null));			// [object Null]

​ 使用 Object 对象的原型方法 toString ,使用 call 进行狸猫换太子,借用Object的 toString 方法结果精准的显示我们需要的数据类型。就算我们改变对象的原型,依然会显示正确的数据类型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章