今天寫JS代碼,遇到動態生成多個名稱相同的input複選按鈕javascript
須要判斷其是不是數組,用到了if (typeof(document.MapCheckMgr.checkid)!="undefined")java
之前用得少,就順便查了一下關於typeof的那些事正則表達式
typeof用以獲取一個變量或者表達式的類型,typeof通常只能返回以下幾個結果:數組
number,boolean,string,function(函數),object(NULL,數組,對象),undefined。瀏覽器
如:函數
alert(typeof (123));//typeof(123)返回"number"
alert(typeof ("123"));//typeof("123")返回"string"測試
咱們可使用typeof來獲取一個變量是否存在,如if(typeof a!="undefined"){},而不要去使用if(a)由於若是a不存在(未聲明)則會出錯,ui
正由於typeof遇到null,數組,對象時都會返回object類型,因此當咱們要判斷一個對象是不是數組時this
或者判斷某個變量是不是某個對象的實例則要選擇使用另外一個關鍵語法instanceofspa
instanceof用於判斷一個變量是否某個對象的實例,如var a=new Array();alert(a instanceof Array);會返回true,
同時alert(a instanceof Object)也會返回true;這是由於Array是object的子類。
再如:function test(){};var a=new test();alert(a instanceof test)會返回true。
1 <script> 2 var str = new String(); 3 4 function show(str1){ 5 6 if(str1 instanceof String){ 7 alert('1'); 8 }else{ 9 alert('0'); 10 } 11 12 } 13 show(str); 14 str = "abccddd"; 15 if(typeof str=='string'){alert(str);} 16 else{alert('0');} 17 </script>
typeof
一元運算符,用來返回操做數類型的字符串。
typeof
幾乎不可能獲得它們想要的結果。typeof
只有一個實際應用場景,就是用來檢測一個對象是否已經定義或者是否已經賦值。而這個應用卻不是來檢查對象的類型。
Value | Class | Type |
---|---|---|
"foo" | String | string |
new String("foo") | String | object |
1.2 | Number | number |
new Number(1.2) | Number | object |
true | Boolean | boolean |
new Boolean(true) | Boolean | object |
new Date() | Date | object |
new Error() | Error | object |
[1,2,3] | Array | object |
new Array(1, 2, 3) | Array | object |
new Function("") | Function | function |
/abc/g | RegExp | object (function in Nitro/V8) |
new RegExp("meow") | RegExp | object (function in Nitro/V8) |
{} | Object | object |
new Object() | Object | object |
上面表格中,Type 一列表示 typeof 操做符的運算結果。能夠看到,這個值在大多數狀況下都返回 "object"。
Class 一列表示對象的內部屬性 [[Class]] 的值。
JavaScript 標準文檔中定義: [[Class]] 的值只多是下面字符串中的一個: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String.
爲了獲取對象的 [[Class]],咱們須要使用定義在 Object.prototype 上的方法 toString。
對象的類定義
JavaScript 標準文檔只給出了一種獲取 [[Class]] 值的方法,那就是使用 Object.prototype.toString。
function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is('String', 'test'); // true is('String', new String('test')); // true
上面例子中,Object.prototype.toString 方法被調用,this 被設置爲了須要獲取 [[Class]] 值的對象。
注:Object.prototype.toString 返回一種標準格式字符串,因此上例能夠經過 slice 截取指定位置的字符串,以下所示:
Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(2) // "[object Number]"
注:這種變化能夠從 IE8 和 Firefox 4 中看出區別,以下所示:
// IE8 Object.prototype.toString.call(null) // "[object Object]" Object.prototype.toString.call(undefined) // "[object Object]" // Firefox 4 Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]"
測試爲定義變量
typeof foo !== 'undefined'
上面代碼會檢測 foo 是否已經定義;若是沒有定義而直接使用會致使 ReferenceError 的異常。 這是 typeof 惟一有用的地方。
結論
爲了檢測一個對象的類型,強烈推薦使用 Object.prototype.toString 方法; 由於這是惟一一個可依賴的方式。正如上面表格所示,typeof 的一些返回值在標準文檔中並未定義, 所以不一樣的引擎實現可能不一樣。
除非爲了檢測一個變量是否已經定義,咱們應儘可能避免使用 typeof 操做符。
x | typeof x |
---|---|
undefined | "undefined" |
true 或false | "boolean" |
任意數字或者NaN | "number" |
任意字符串 | "string" |
函數對象(在ECMA-262術語中,指的是實現了[[Call]] 的對象) | "function" |
任意內置對象(非函數) | "object" |
數組 | "obeject" |
null | "object" |
宿主對象(JS引擎內置對象,而不是DOM或者其餘提供的) | 由編譯器各自實現的字符串,但不是"undefined","number","boolean","number","string"。 |
正則表達式 | 各瀏覽器表現不一 |
若是想將null和對象區分開,則必須針對特殊值顯式檢測。如:my_value===null
。對於宿主對象來講,typeof有可能並不返回‘object’,而返回字符串。但實際上客戶端js中的大多數宿主對象都是‘object’類型。對於全部內置可執行對象進行typeof運算都將返回「function」。
// Numbers typeof 37 === 'number'; typeof 3.14 === 'number'; typeof Math.LN2 === 'number'; typeof Infinity === 'number'; typeof NaN === 'number'; // 儘管NaN是"Not-A-Number"的縮寫,意思是"不是一個數字" typeof Number(1) === 'number'; // 不要這樣使用! // Strings typeof "" === 'string'; typeof "bla" === 'string'; typeof (typeof 1) === 'string'; // typeof返回的確定是一個字符串 typeof String("abc") === 'string'; // 不要這樣使用! // Booleans typeof true === 'boolean'; typeof false === 'boolean'; typeof Boolean(true) === 'boolean'; // 不要這樣使用! // Undefined typeof undefined === 'undefined'; typeof blabla === 'undefined'; // 一個未定義的變量,或者一個定義了卻未賦初值的變量 // Objects typeof {a:1} === 'object'; typeof [1, 2, 4] === 'object'; // 使用Array.isArray或者Object.prototype.toString.call方法 //能夠分辨出一個數組和真實的對象 typeof new Date() === 'object'; typeof new Boolean(true) === 'object' // 使人困惑.不要這樣使用 typeof new Number(1) === 'object' // 使人困惑.不要這樣使用 typeof new String("abc") === 'object'; // 使人困惑.不要這樣使用 // Functions typeof function(){} === 'function'; typeof Math.sin === 'function';
instanceof 左操做數是一個類,右操做數是標識對象的類。若是左側的對象是右側類的實例,則返回true.而js中對象的類是經過初始化它們的構造函數來定義的。即instanceof的右操做數應當是一個函數。全部的對象都是object的實例。若是左操做數不是對象,則返回false,若是右操做數不是函數,則拋出typeError。
instanceof 運算符是用來測試一個對象是否在其原型鏈原型構造函數的屬性。其語法是object instanceof constructor
instanceof 操做符用來比較兩個操做數的構造函數。只有在比較自定義的對象時纔有意義。 若是用來比較內置類型,將會和 typeof 操做符 同樣用處不大。
比較自定義對象
function Foo() {} function Bar() {} Bar.prototype = new Foo(); new Bar() instanceof Bar; // true new Bar() instanceof Foo; // true // 若是僅僅設置 Bar.prototype 爲函數 Foo 自己,而不是 Foo 構造函數的一個實例 Bar.prototype = Foo; new Bar() instanceof Foo; // false
instanceof 比較內置類型
new String('foo') instanceof String; // true new String('foo') instanceof Object; // true 'foo' instanceof String; // false 'foo' instanceof Object; // false
有一點須要注意,instanceof 用來比較屬於不一樣 JavaScript 上下文的對象(好比,瀏覽器中不一樣的文檔結構)時將會出錯, 由於它們的構造函數不會是同一個對象。
結論:instanceof 操做符應該僅僅用來比較來自同一個 JavaScript 上下文的自定義對象。 正如 typeof 操做符同樣,任何其它的用法都應該是避免的。
function C(){} // defining a constructor function D(){} // defining another constructor var o = new C(); o instanceof C; // true, because: Object.getPrototypeOf(o) === C.prototype o instanceof D; // false, because D.prototype is nowhere in o's prototype chain o instanceof Object; // true, because: C.prototype instanceof Object // true C.prototype = {}; var o2 = new C(); o2 instanceof C; // true o instanceof C; // false, because C.prototype is nowhere in o's prototype chain anymore D.prototype = new C(); // use inheritance var o3 = new D(); o3 instanceof D; // true o3 instanceof C; // true
var myString = new String(); var myDate = new Date(); myString instanceof String; // returns true myString instanceof Object; // returns true myString instanceof Date; // returns false myDate instanceof Date; // returns true myDate instanceof Object; // returns true myDate instanceof String; // returns false
function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } var mycar = new Car("Honda", "Accord", 1998); var a = mycar instanceof Car; // returns true var b = mycar instanceof Object; // returns true