摘要:如果左側(cè)的對(duì)象是右側(cè)類(lèi)的實(shí)例,則返回而中對(duì)象的類(lèi)是通過(guò)初始化它們的構(gòu)造函數(shù)來(lái)定義的。其語(yǔ)法是操作符用來(lái)比較兩個(gè)操作數(shù)的構(gòu)造函數(shù)。
關(guān)于typeof
typeof一元運(yùn)算符,用來(lái)返回操作數(shù)類(lèi)型的字符串。
typeof幾乎不可能得到它們想要的結(jié)果。typeof只有一個(gè)實(shí)際應(yīng)用場(chǎng)景,就是用來(lái)檢測(cè)一個(gè)對(duì)象是否已經(jīng)定義或者是否已經(jīng)賦值。而這個(gè)應(yīng)用卻不是來(lái)檢查對(duì)象的類(lèi)型。
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 操作符的運(yùn)算結(jié)果。可以看到,這個(gè)值在大多數(shù)情況下都返回 "object"。
Class 一列表示對(duì)象的內(nèi)部屬性 [[Class]] 的值。
JavaScript 標(biāo)準(zhǔn)文檔中定義: [[Class]] 的值只可能是下面字符串中的一個(gè): Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String.
為了獲取對(duì)象的 [[Class]],我們需要使用定義在 Object.prototype 上的方法 toString。
對(duì)象的類(lèi)定義
JavaScript 標(biāo)準(zhǔn)文檔只給出了一種獲取 [[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 方法被調(diào)用,this 被設(shè)置為了需要獲取 [[Class]] 值的對(duì)象。
注:Object.prototype.toString 返回一種標(biāo)準(zhǔn)格式字符串,所以上例可以通過(guò) slice 截取指定位置的字符串,如下所示:
Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(2) // "[object Number]"
注:這種變化可以從 IE8 和 Firefox 4 中看出區(qū)別,如下所示:
// 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]"
測(cè)試為定義變量
typeof foo !== "undefined"
上面代碼會(huì)檢測(cè) foo 是否已經(jīng)定義;如果沒(méi)有定義而直接使用會(huì)導(dǎo)致 ReferenceError 的異常。 這是 typeof 唯一有用的地方。
結(jié)論
為了檢測(cè)一個(gè)對(duì)象的類(lèi)型,強(qiáng)烈推薦使用 Object.prototype.toString 方法; 因?yàn)檫@是唯一一個(gè)可依賴(lài)的方式。正如上面表格所示,typeof 的一些返回值在標(biāo)準(zhǔn)文檔中并未定義, 因此不同的引擎實(shí)現(xiàn)可能不同。
除非為了檢測(cè)一個(gè)變量是否已經(jīng)定義,我們應(yīng)盡量避免使用 typeof 操作符。
x | typeof x |
---|---|
undefined | "undefined" |
true 或false | "boolean" |
任意數(shù)字或者NaN | "number" |
任意字符串 | "string" |
函數(shù)對(duì)象(在ECMA-262術(shù)語(yǔ)中,指的是實(shí)現(xiàn)了[[Call]] 的對(duì)象) | "function" |
任意內(nèi)置對(duì)象(非函數(shù)) | "object" |
數(shù)組 | "obeject" |
null | "object" |
宿主對(duì)象(JS引擎內(nèi)置對(duì)象,而不是DOM或者其他提供的) | 由編譯器各自實(shí)現(xiàn)的字符串,但不是"undefined","number","boolean","number","string"。 |
正則表達(dá)式 | 各瀏覽器表現(xiàn)不一 |
如果想將null和對(duì)象區(qū)分開(kāi),則必須針對(duì)特殊值顯式檢測(cè)。如:my_value===null。對(duì)于宿主對(duì)象來(lái)說(shuō),typeof有可能并不返回‘object’,而返回字符串。但實(shí)際上客戶(hù)端js中的大多數(shù)宿主對(duì)象都是‘object’類(lèi)型。對(duì)于所有內(nèi)置可執(zhí)行對(duì)象進(jìn)行typeof運(yùn)算都將返回“function”。
// Numbers typeof 37 === "number"; typeof 3.14 === "number"; typeof Math.LN2 === "number"; typeof Infinity === "number"; typeof NaN === "number"; // 盡管NaN是"Not-A-Number"的縮寫(xiě),意思是"不是一個(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"; // 不要這樣使用! // Undefined typeof undefined === "undefined"; typeof blabla === "undefined"; // 一個(gè)未定義的變量,或者一個(gè)定義了卻未賦初值的變量 // Objects typeof {a:1} === "object"; typeof [1, 2, 4] === "object"; // 使用Array.isArray或者Object.prototype.toString.call方法 //可以分辨出一個(gè)數(shù)組和真實(shí)的對(duì)象 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 左操作數(shù)是一個(gè)類(lèi),右操作數(shù)是標(biāo)識(shí)對(duì)象的類(lèi)。如果左側(cè)的對(duì)象是右側(cè)類(lèi)的實(shí)例,則返回true.而js中對(duì)象的類(lèi)是通過(guò)初始化它們的構(gòu)造函數(shù)來(lái)定義的。即instanceof的右操作數(shù)應(yīng)當(dāng)是一個(gè)函數(shù)。所有的對(duì)象都是object的實(shí)例。如果左操作數(shù)不是對(duì)象,則返回false,如果右操作數(shù)不是函數(shù),則拋出typeError。
instanceof 運(yùn)算符是用來(lái)測(cè)試一個(gè)對(duì)象是否在其原型鏈原型構(gòu)造函數(shù)的屬性。其語(yǔ)法是object instanceof constructor
instanceof 操作符用來(lái)比較兩個(gè)操作數(shù)的構(gòu)造函數(shù)。只有在比較自定義的對(duì)象時(shí)才有意義。 如果用來(lái)比較內(nèi)置類(lèi)型,將會(huì)和 typeof 操作符 一樣用處不大。
比較自定義對(duì)象
function Foo() {} function Bar() {} Bar.prototype = new Foo(); new Bar() instanceof Bar; // true new Bar() instanceof Foo; // true // 如果僅僅設(shè)置 Bar.prototype 為函數(shù) Foo 本身,而不是 Foo 構(gòu)造函數(shù)的一個(gè)實(shí)例 Bar.prototype = Foo; new Bar() instanceof Foo; // false
instanceof 比較內(nèi)置類(lèi)型
new String("foo") instanceof String; // true new String("foo") instanceof Object; // true "foo" instanceof String; // false "foo" instanceof Object; // false
有一點(diǎn)需要注意,instanceof 用來(lái)比較屬于不同 JavaScript 上下文的對(duì)象(比如,瀏覽器中不同的文檔結(jié)構(gòu))時(shí)將會(huì)出錯(cuò), 因?yàn)樗鼈兊臉?gòu)造函數(shù)不會(huì)是同一個(gè)對(duì)象。
結(jié)論:instanceof 操作符應(yīng)該僅僅用來(lái)比較來(lái)自同一個(gè) JavaScript 上下文的自定義對(duì)象。 正如 typeof 操作符一樣,任何其它的用法都應(yīng)該是避免的。
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
引用資料:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
http://bonsaiden.github.io/JavaScript-Garden/zh/#types.instanceof
https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Operators/typeof
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/87651.html
摘要:中和常用來(lái)判斷一個(gè)變量是否為空,或者是什么類(lèi)型的。運(yùn)算符返回一個(gè)用來(lái)表示表達(dá)式的數(shù)據(jù)類(lèi)型的字符串。運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的屬性。檢查原型鏈會(huì)找到同上 JavaScript 中typeof 和 instanceof 常用來(lái)判斷一個(gè)變量是否為空,或者是什么類(lèi)型的。但它們之間還是有區(qū)別的: typeof typeof 是一個(gè)一元運(yùn)算,放在一個(gè)運(yùn)算數(shù)之前,運(yùn)算數(shù)...
摘要:運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的屬性。多個(gè)窗口意味著多個(gè)全局環(huán)境,不同的全局環(huán)境擁有不同的全局對(duì)象,從而擁有不同的內(nèi)置類(lèi)型構(gòu)造函數(shù)。 instanceofinstanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性。語(yǔ)法object instanceof constructor描述instanceof 運(yùn)算符用來(lái)檢測(cè) ...
摘要:類(lèi)型的實(shí)例首先要理解的含義是例子的意思,實(shí)際上是判斷是否是的一個(gè)實(shí)例。 數(shù)據(jù)類(lèi)型深入理解 數(shù)據(jù)類(lèi)型分類(lèi) 基本(值)類(lèi)型(5種) String:任意字符串 Number:任意的數(shù)字 boolean:true/false null:null undefined:undefined 對(duì)象(引用)類(lèi)型(3種) Object:任意對(duì)象 Array:一種特別的對(duì)象(數(shù)值下...
摘要:需要測(cè)試的函數(shù)構(gòu)造函數(shù)即用運(yùn)算符來(lái)檢測(cè)是否存在參數(shù)的原型鏈。區(qū)別只能用來(lái)判斷對(duì)象函數(shù)和數(shù)組,不能用來(lái)判斷字符串和數(shù)字等用于判斷一個(gè)表達(dá)式的原始值,返回一個(gè)字符串。一般返回結(jié)果有函數(shù)數(shù)組,對(duì)象。 最近開(kāi)始在整理ES6/ES7/ES8/ES9的知識(shí)點(diǎn)(已經(jīng)上傳到 我的博客 上),碰到一些知識(shí)點(diǎn)是自己已經(jīng)忘記(用得少的知識(shí)點(diǎn)),于是也重新復(fù)習(xí)了一遍。 這篇文章要復(fù)習(xí)的 instanc...
摘要:所以不論你媽媽是喊,狗蛋回家吃飯了,還是喊小明回家吃飯了,其實(shí)喊的都是你。當(dāng)然的嘛狗蛋買(mǎi)了件新衣服,小明當(dāng)然就有這件新衣服了。。。 上一章--原型鏈講解:傳送門(mén):https://segmentfault.com/a/11... 在上一章講解原型鏈時(shí)提到了:所有的引用類(lèi)型都有一個(gè)_proto_屬性,稱(chēng)之為隱式原型。那么引用類(lèi)型是什么鬼? 盡量簡(jiǎn)單的講解一下javascript中的數(shù)據(jù)類(lèi)...
閱讀 917·2021-09-09 09:32
閱讀 2884·2021-09-02 10:20
閱讀 2706·2021-07-23 11:24
閱讀 835·2019-08-30 15:54
閱讀 3638·2019-08-30 15:54
閱讀 1351·2019-08-30 11:02
閱讀 2852·2019-08-26 17:40
閱讀 1133·2019-08-26 13:55