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 方法結果精準的顯示我們需要的數據類型。就算我們改變對象的原型,依然會顯示正確的數據類型。

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