欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

談?wù)勎覍?duì)JavaScript中typeof和instanceof的深入理解

 更新時(shí)間:2015年12月25日 14:28:48   投稿:mrr  
這次主要說(shuō)說(shuō)javascript的類型判斷函數(shù)typeof和判斷構(gòu)造函數(shù)原型instanceof的用法和注意的地方,對(duì)本文感興趣的朋友一起看看吧

這次主要說(shuō)說(shuō)javascript的類型判斷函數(shù)typeof和判斷構(gòu)造函數(shù)原型instanceof的用法和注意的地方。

typeof

先來(lái)說(shuō)說(shuō)typeof吧。首先需要注意的是,typeof方法返回一個(gè)字符串,來(lái)表示數(shù)據(jù)的類型。

typeof 是一個(gè)一元運(yùn)算,放在一個(gè)運(yùn)算數(shù)之前,運(yùn)算數(shù)可以是任意類型。

它返回值是一個(gè)字符串,該字符串說(shuō)明運(yùn)算數(shù)的類型。typeof 一般只能返回如下幾個(gè)結(jié)果:
number,boolean,string,function,object,undefined。我們可以使用 typeof 來(lái)獲取一個(gè)變量是否存在,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 因?yàn)槿绻?a 不存在(未聲明)則會(huì)出錯(cuò),對(duì)于 Array,Null 等特殊對(duì)象使用 typeof 一律返回 object,這正是 typeof 的局限性。

語(yǔ)法講解

我們先看看各個(gè)數(shù)據(jù)類型對(duì)應(yīng)typeof的值:

數(shù)據(jù)類型 Type
Undefined “undefined”
Null “object”
布爾值 “boolean”
數(shù)值 “number”
字符串 “string”
Symbol (ECMAScript 6 新增) “symbol”
宿主對(duì)象(JS環(huán)境提供的,比如瀏覽器) Implementation-dependent
函數(shù)對(duì)象 “function”
任何其他對(duì)象 “object”

再看看具體的實(shí)例:

// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 盡管NaN是"Not-A-Number"的縮寫,意思是"不是一個(gè)數(shù)字"
typeof Number(1) === 'number'; // 不要這樣使用!
// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof返回的肯定是一個(gè)字符串
typeof String("abc") === 'string'; // 不要這樣使用!
// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 不要這樣使用!
// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';
// Undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined'; // 一個(gè)未定義的變量,或者一個(gè)定義了卻未賦初值的變量
// Objects
typeof {a:1} === 'object';
// 使用Array.isArray或者Object.prototype.toString.call方法可以從基本的對(duì)象中區(qū)分出數(shù)組類型
typeof [1, 2, 4] === 'object';
typeof new Date() === 'object';
// 下面的容易令人迷惑,不要這樣使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) ==== 'object';
typeof new String("abc") === 'object';
// 函數(shù)
typeof function(){} === 'function';
typeof Math.sin === 'function';

我們會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,就是typeof來(lái)判斷數(shù)據(jù)類型其實(shí)并不準(zhǔn)確。比如數(shù)組、正則、日期、對(duì)象的typeof返回值都是object,這就會(huì)造成一些誤差。

所以在typeof判斷類型的基礎(chǔ)上,我們還需要利用Object.prototype.toString方法來(lái)進(jìn)一步判斷數(shù)據(jù)類型。

我們來(lái)看看在相同數(shù)據(jù)類型的情況下,toString方法和typeof方法返回值的區(qū)別:

數(shù)據(jù) toString typeof
“foo” String string
new String(“foo”) String object
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
new Array(1, 2, 3) Array object
/abc/g RegExp object
new RegExp(“meow”) RegExp object

可以看到利用toString方法可以正確區(qū)分出Array、Error、RegExp、Date等類型。

所以我們一般通過(guò)該方法來(lái)進(jìn)行數(shù)據(jù)類型的驗(yàn)證

真題檢測(cè)

但是既然今天說(shuō)到了typeof,那這里就列出幾道題目,來(lái)看看自己是否真正掌握了typeof的用法。

第一題:

var y = 1, x = y = typeof x;
x;

第二題:

(function f(f){
return typeof f();
})(function(){ return 1; });

第三題:

var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();
})(foo.bar);

第四題:

var foo = {
bar: function(){ return this.baz; },
baz: 1
}
typeof (f = foo.bar)();

第五題:

var f = (function f(){ return "1"; }, function g(){ return 2; })();
typeof f;

第六題:

var x = 1;
if (function f(){}) {
x += typeof f;
}
x;

第七題:

(function(foo){
return typeof foo.bar;
})({ foo: { bar: 1 } });

下面公布答案了,這七題的答案分別是:

"undefined","number","undefined","undefined","number","1undefined","undefined"

做對(duì)了幾道呢?是不是很大的困惑呢?這幾題雖然都有typeof,但是考察了很多javascript的基礎(chǔ)噢。下面我們來(lái)一一詳解。

第一題:

var y = 1, x = y = typeof x;
x;//"undefined"

表達(dá)式是從右往左的,x由于變量提升,類型不是null,而是undefined,所以x=y=”undefined”。

變量提升我在這篇文章中提到過(guò),可以看看。

第二題:

(function f(f){
return typeof f();//"number"
})(function(){ return 1; });

傳入的參數(shù)為f也就是function(){ return 1; }這個(gè)函數(shù)。通過(guò)f()執(zhí)行后,得到結(jié)果1,所以typeof 1返回”number”。這道題很簡(jiǎn)單,主要是區(qū)分f和f()。

第三題:

var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();//"undefined"
})(foo.bar);

這一題考察的是this的指向。this永遠(yuǎn)指向函數(shù)執(zhí)行時(shí)的上下文,而不是定義時(shí)的(ES6的箭頭函數(shù)不算)。當(dāng)arguments執(zhí)行時(shí),this已經(jīng)指向了window對(duì)象。所以是”undefined”。對(duì)this執(zhí)行不熟悉的同學(xué)可以看看這篇文章:深入理解this,對(duì)剛剛提到的箭頭函數(shù)感興趣的同學(xué)可以看看初步探究ES6之箭頭函數(shù)。

第四題:

var foo = {
bar: function(){ return this.baz; },
baz: 1
}
typeof (f = foo.bar)();//undefined

如果上面那一題做對(duì)了,那么這一題也應(yīng)該不會(huì)錯(cuò),同樣是this的指向問(wèn)題。

第五題:

var f = (function f(){ return "1"; }, function g(){ return 2; })();
typeof f;//"number"

這一題比較容易錯(cuò),因?yàn)槲以谟龅竭@道題之前也從來(lái)沒(méi)有遇到過(guò)javascript的分組選擇符。什么叫做分組選擇符呢?舉一個(gè)例子就會(huì)明白了:

var a = (1,2,3);
document.write(a);//3,會(huì)以最后一個(gè)為準(zhǔn)

所以上面的題目會(huì)返回2,typeof 2當(dāng)然是”number”啦。

第六題:

var x = 1;
if (function f(){}) {
x += typeof f;
}
x;//"1undefined"

這是一個(gè)javascript語(yǔ)言規(guī)范上的問(wèn)題,在條件判斷中加入函數(shù)聲明。這個(gè)聲明語(yǔ)句本身沒(méi)有錯(cuò),也會(huì)返回true,但是javascript引擎在搜索的時(shí)候卻找不到該函數(shù)。所以結(jié)果為”1undefined”。

第七題:

(function(foo){
return typeof foo.bar;
})({ foo: { bar: 1 } });

這題其實(shí)是一個(gè)考察心細(xì)程度的題目。形參的foo指向的是{ foo: { bar: 1 } }這個(gè)整體。相信這么說(shuō)就明白了。

好啦。上面的題目都是很好的資源噢。

instanceof

接下來(lái)該說(shuō)說(shuō)instanceof方法了。instanceof運(yùn)算符可以用來(lái)判斷某個(gè)構(gòu)造函數(shù)的prototype屬性是否存在于另外一個(gè)要檢測(cè)對(duì)象的原型鏈上。

instanceof 用于判斷一個(gè)變量是否某個(gè)對(duì)象的實(shí)例,如 var a=new Array();alert(a instanceof Array); 會(huì)返回 true,同時(shí) alert(a instanceof Object) 也會(huì)返回 true;這是因?yàn)?Array 是 object 的子類。再如:function test(){};var a=new test();alert(a instanceof test) 會(huì)返回

談到 instanceof 我們要多插入一個(gè)問(wèn)題,就是 function 的 arguments,我們大家也許都認(rèn)為 arguments 是一個(gè) Array,但如果使用 instaceof 去測(cè)試會(huì)發(fā)現(xiàn) arguments 不是一個(gè) Array 對(duì)象,盡管看起來(lái)很像。

如果對(duì)原型不太了解,可以看看深入理解原型。

下面我們看看instanceof的實(shí)例:

// 定義構(gòu)造函數(shù)
function C(){} 
function D(){} 
var o = new C();
// true,因?yàn)?Object.getPrototypeOf(o) === C.prototype
o instanceof C; 
// false,因?yàn)?D.prototype不在o的原型鏈上
o instanceof D; 
o instanceof Object; // true,因?yàn)镺bject.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指向了一個(gè)空對(duì)象,這個(gè)空對(duì)象不在o的原型鏈上.
D.prototype = new C(); // 繼承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

但是這里我們需要注意一個(gè)問(wèn)題:

function f(){ return f; }
document.write(new f() instanceof f);//false
function g(){}
document.write(new g() instanceof g);//true

第一個(gè)為什么返回false呢?因?yàn)闃?gòu)造函數(shù)的原型被覆蓋了,我們可以看看new f和new g的區(qū)別:

相關(guān)文章

最新評(píng)論