typeof和instanceof都可以用來判斷變量,它們的用法有很大區別
typeof會返回一個變量的基本類型,instanceof返回的是一個布爾值,需要注意的是,instanceof只能用來判斷對象和函數,不能用來判斷字符串和數字等
先說instanceof
instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。
語法
object instanceof constructor
描述
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上。
理解:object.__proto__ === constructor.prototype ? => boolean
定義構造函數 function C(){} function D(){} var o = new C(); o instanceof C; // true,因為Object.getPrototypeOf(o) === C.prototype // 擴展:可以理解為 o.__proto__ === C.prototype o instanceof D; // false,D.prototype不在o的原型鏈上 o instaceof Object; // true,Object.prototype.isPrototypeOf(o) 返回true C.prototype instanceof Object // true ,同上 C.prototype = {}; var o2 = new C(); o2 instanceof C; // true o instanceof C; // false,C.prototype指向一個空對象,這個空對象不在o的原型鏈上 D.prototype = new C(); // 繼承 var o3 = new D(); o3 instanceof D; // true o3 instanceof C; // true
如果表達式 obj instanceof Foo 返回true,則並不意味着該表達式會永遠返回true,因為Foo.prototype屬性的值有可能會改變,改變之后的值很有可能不存在於obj的原型鏈上,這時原表達式的值就會成為false。另外一種情況下,原表達式的值也會改變,就是改變對象obj的原型鏈的情況,雖然在目前的ES規范中,我們只能讀取對象的原型而不能改變它,但借助於非標准的__proto__魔法屬性,是可以實現的。比如執行obj.__proto__ = {}之后,obj instanceof Foo就會返回false了。
String和Date對象同時也屬於Object類型
var simpleStr = "some simple string"; var myString = new String(); var newStr = new String("String created with constructor"); var myDate = new Date(); var myObj = {}; simpleStr instanceof String; // false,檢查原型鏈會找到undefined myString instanceof String; // true newStr instanceof String; // true myString instanceof Object; // true myObj instanceof Object; // true ({}) instanceof Object; // true myString instanceof Date; // false myDate instanceof Date; // true myDate instanceof Object; // true myDate instanceof String; // false
typeof
typeof操作符返回一個字符串,指示未經計算的操作數的類型。
最新的 ECMAScript 標准定義了 8 種數據類型:
- 6 種原始類型,使用 typeof 運算符檢查:
- null:
typeof instance === "object"
。 - Object:
typeof instance === "object"
。任何 constructed 對象實例的特殊非數據結構類型,也用做數據結構:new Object,new Array,new Map,new Set,new WeakMap,new WeakSet,new Date,和幾乎所有通過 new keyword 創建的東西。
記住 typeof
操作符的唯一目的就是檢查數據類型,如果我們希望檢查任何從 Object 派生出來的結構類型,使用 typeof
是不起作用的,因為總是會得到 "object"
。檢查 Object 種類的合適方式是使用 instanceof 關鍵字。但即使這樣也存在誤差。
(以上摘自MDN Web Docs)
如果我們想要判斷一個變量是否存在,可以使用typeof:(不能使用if(a) 若a未聲明,則報錯)
if(typeof a != 'undefined'){ //變量存在 }
typeof用於判斷數據類型,返回值為6個字符串,分別為string
、Boolean
、number
、function
、object
、undefined
。
var a = [34,4,3,54], b = 34, c = 'adsfas', d = function(){}, e = true, f = null, g; console.log(typeof(a));//object console.log(typeof(b));//number console.log(typeof(c));//string console.log(typeof(d));//function console.log(typeof(e));//boolean console.log(typeof(f));//object console.log(typeof(g));//undefined
typeof
在判斷
null
、
array
、
object
以及函數實例
(new + 函數)
時,得到的都是
object
。這使得在判斷這些數據類型的時候,得不到真是的數據類型。由此引出
instanceof
。
instanceof
判斷該對象是誰的實例,同時我們也就知道instanceof是對象運算符。
這里的實例就牽扯到了對象的繼承,它的判斷就是根據原型鏈進行搜尋,在對象obj1的原型鏈上如果存在另一個對象obj2的原型屬性,那么表達式(obj1 instanceof obj2)返回值為true;否則返回false。
- typeof判斷所有變量的類型,返回值有number,boolean,string,function,object,undefined。
- typeof對於豐富的對象實例,只能返回"Object"字符串。
- instanceof用來判斷對象,代碼形式為obj1 instanceof obj2(obj1是否是obj2的實例),obj2必須為對象,否則會報錯!其返回值為布爾值。
- instanceof可以對不同的對象實例進行判斷,判斷方法是根據對象的原型鏈依次向下查詢,如果obj2的原型屬性存在obj1的原型鏈上,(obj1 instanceof obj2)值為true。