JavaScript 三種方法,可以確定一個(gè)值到底是什么類型。
typeof為什么需要確定類型 ?
instanceof
Object.prototype.toString
? 只有確定類型的情況,才知道當(dāng)前操作對(duì)象擁有哪些功能; 比如使用 push,unshfit,shfit 等方法時(shí),那么其必須為數(shù)組類型時(shí)才能正確使用;
? 當(dāng)某些情況添加類型檢查時(shí),這樣代碼更加健壯,安全;
typeof 運(yùn)算符返回一個(gè)值的數(shù)據(jù)類型。
基本語法:
typeof operand or typeof (operand)
operand 是一個(gè)表達(dá)式,表示對(duì)象或原始值,其類型將被返回。括號(hào)是可選的.
示例:基本數(shù)據(jù)類型{ typeof 1 // "number" typeof Number(1) // "number" typeof "" // "string" typeof true // "boolean" typeof null // "object" typeof undefined // "undefined" typeof Symbol // "function" }
當(dāng)操作數(shù)(operand)為基本數(shù)據(jù)類型,其返回字符串與期望一樣,也能夠辨別當(dāng)前操作數(shù)得類型;
這里需要提及下基本數(shù)據(jù)類型 null ,為什么 typeof null 返回的字符串為 "object";
在 JavaScript 最初的實(shí)現(xiàn)中,JavaScript 中的值是由一個(gè)表示類型的標(biāo)簽和實(shí)際數(shù)據(jù)值表示的。對(duì)象的類型標(biāo)簽是 0。由于 null 代表的是空指針(大多數(shù)平臺(tái)下值為 0x00),因此,null的類型標(biāo)簽也成為了 0,typeof null就錯(cuò)誤的返回了"object"。
示例:引用數(shù)據(jù)類型typeof new Number(1) // "object" typeof new String() // "object" typeof new Array() // "object" typeof new Date() // "object" typeof new Function() // "function"
從上面看出,所有通過 new 關(guān)鍵實(shí)例化的構(gòu)造函數(shù)返回都 object 類型. 當(dāng)然函數(shù)是一個(gè)例外;
從上述兩個(gè)示例可以看出,當(dāng)typeof 的操作數(shù)為基本數(shù)據(jù)類型、函數(shù)返回字符串能夠區(qū)分其數(shù)據(jù)類型;
那么如果需要區(qū)分引用類型時(shí)需要借助 JavaScript中另外一個(gè)運(yùn)算符;
instanceof 運(yùn)算符判斷實(shí)例對(duì)象是不是類(構(gòu)造函數(shù))的實(shí)例
instanceof 工作原理基于原型鏈,也就是說如果在對(duì)象的原型鏈上能夠找到構(gòu)造函數(shù)的 prototype 對(duì)象,那么該操作就返回 true;
基本語法:**
object instanceof constructor
參數(shù)
object
要檢測(cè)的對(duì)象.
constructor
某個(gè)構(gòu)造函數(shù)
let o = new Object(); let bool = new Boolean(); let num = new Number(1); let str = new String(); let arr = new Array(); // 自定義構(gòu)造函數(shù) function Person(){} function Animal(){} let person = new Person(); let animal = new Animal(); person instanceof Person // true animal instanceof Animal // true o instanceof Object; // true bool instanceof Boolean; // true num instanceof Number; // true str instanceof String; // true arr instanceof Array; // true
這樣彌補(bǔ) typeof 在檢測(cè)引用類型的時(shí)的問題;
通過下面的示例,驗(yàn)證下 instanceof 工作原理:
{ function Person(){} function Animal(){} // 例如自定義定義兩個(gè)類 let person = new Person(); let animal = new Animal(); console.log(animal instanceof Object); // => true console.log(animal instanceof Animal); // true console.log(person instanceof Object); // => true console.log(person instanceof Person); // true console.log(person instanceof Animal); // => false console.log(animal instanceof Person); // => false }
上面應(yīng)該跟我們預(yù)期的一樣, 那么有沒有通過一種辦法讓
person instanceof Animal // => true
那么來針對(duì)上面作如下調(diào)整:
person.__proto__ = Animal.prototype; console.log(person instanceof Animal) // => true console.log(person instanceof Person) // => false
嚴(yán)格意義上來說, 上述這么改是沒有意思;這里只是為了驗(yàn)證 instanceof 如何工作的;其次說明 person instanceof Person 返回 true, 則并不意味著給表達(dá)式永遠(yuǎn)返回 true, Person.prototype 和 person.__proto__ 都是可變的;
instanceof 和多個(gè)全局對(duì)象(多個(gè)frame或多個(gè)window之間的交互)可以定義兩個(gè)頁面測(cè)試: parent.html、 child.html
// parent.html
// child.html
嚴(yán)格上來說value 就是數(shù)組,但parent頁面中打印輸出: false ;也就是 parent 頁面中 Array.prototype != window.frames[0].Array.prototype ;
主要引起問題是,因?yàn)槎鄠€(gè)窗口意味著多個(gè)全局環(huán)境,不同的全局環(huán)境擁有不同的全局對(duì)象,從而擁有不同的內(nèi)置類型構(gòu)造函數(shù).
instanceof 應(yīng)用 - 檢測(cè)作用域的安全function Person(name, age){ this.name = name; this.age = age } // 正常情況下 { let person = new Person("托尼", 20); console.log(person.name,person.age); } // 假如在實(shí)例化時(shí)候忘記添加 new 關(guān)鍵字尼? 會(huì)出現(xiàn)什么情況尼? { let person = Person("托尼", 20); console.log(person.name, person.age); // Uncaught TypeError: Cannot read property "name" of undefined // Person 被當(dāng)作普通的方法執(zhí)行,其次 name ,age 被添加window上 console.log(name, age); //=> 托尼 20 } // 如何避免這樣情況,在加 new 關(guān)鍵字或省略時(shí)候都能正常返回實(shí)例對(duì)象 { function Person(name, age){ if(this instanceof Person) { this.name = name; this.age = age return this; }else { return new Person(name, age); } } let person = Person("托尼", 20); console.log(person.name, person.age); // 托尼 20 }Object.prototype.toString 方法
默認(rèn)情況下(不覆蓋 toString 方法前提下),任何一個(gè)對(duì)象調(diào)用 Object 原生的 toString 方法都會(huì)返回 "[object type]",其中 type 是對(duì)象的類型;
每個(gè)類的內(nèi)部都有一個(gè) [[Class]] 屬性,這個(gè)屬性中就指定了上述字符串中的 type(構(gòu)造函數(shù)名) ;
舉個(gè)例子吧:
console.log(Object.prototype.toString.call([])); // [object Array]
上述中: Array 對(duì)應(yīng)也就當(dāng)前對(duì)象的 type,同樣就是當(dāng)前對(duì)象的構(gòu)造函數(shù)名;
前面在說 instanceof 在多個(gè)作用域的情況下,嘗試用這種方式解決:
function isArray(arr){ return Object.prototype.toString.call(arr) === "[object Array]" } console.log(isArray(value)); // true
從輸出來看時(shí)完美解決了;
為什么這種方式是可以咧?這里辨別類型根據(jù) 構(gòu)造函數(shù)名稱,由于原生數(shù)組的構(gòu)造函數(shù)名稱與全局作用域無關(guān),因此使用 toString() 就能保證返回一致的值。
同理其它原生對(duì)象檢測(cè)也能按照這種方式來,如 Date,RegExp,F(xiàn)unction
function isFunction(value) { return Object.prototype.toString.call(value) === "[object Function]" } function isDate(value) { return Object.prototype.toString.call(value) === "[object Date]" } function isRegExp(value) { return Object.prototype.toString.call(value) === "[object RegExp]" } isDate(new Date()); // true isRegExp(/w/); // true isFunction(function(){}); //true
上述代碼,可以作進(jìn)一步改進(jìn),由于 isFunction、isDate、isRegExp 方法中,其實(shí)只有 [object ConstructorName] ConstructorName不一樣,可以利用工廠函數(shù)再修飾一下:
function generator(type){ return function(value){ return Object.prototype.toString.call(value) === "[object "+ type +"]" } } let isFunction = generator("Function") let isArray = generator("Array"); let isDate = generator("Date"); let isRegExp = generator("RegExp"); isArray([])); // true isDate(new Date()); // true isRegExp(/w/); // true isFunction(function(){}); //true
這樣即使要生成其它原生對(duì)象驗(yàn)證函數(shù)前面時(shí)就簡(jiǎn)單多了;
總結(jié):typeof 適用于檢測(cè)值類型, 特別注意 null 的問題,這也是面試用經(jīng)常遇到的.
instanceof 檢測(cè)引用類型.
toString 彌補(bǔ) instanceof 在跨窗口下對(duì)類型檢測(cè)問題, toString 只適應(yīng)于原生對(duì)象;
對(duì)于用戶自定義的對(duì)象無法區(qū)分的.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100084.html
摘要:閉包,原型,原型鏈,繼承對(duì)象若干屬性的集合輸出的集中類型標(biāo)識(shí),其中上面的四種屬于簡(jiǎn)單的值類型,不是對(duì)象。在實(shí)際應(yīng)用中如何區(qū)分一個(gè)屬性到底是基本的還是從原型中找到的呢,特別是在循環(huán)中由于所有的對(duì)象的原型鏈都會(huì)找到,因此所有的對(duì)象都會(huì)有的方法。 閉包,原型,原型鏈,繼承 對(duì)象——若干屬性的集合 typeof輸出的集中類型標(biāo)識(shí),其中上面的四種(undefined, number, strin...
摘要:共享原型鏈現(xiàn)在我們還有另一個(gè)對(duì)象如圖那么和其實(shí)是同一東西,也就是。改進(jìn)通過第一節(jié)可以知道,我們可以通過原型鏈來解決重復(fù)創(chuàng)建的問題我們先創(chuàng)建一個(gè)士兵原型,然后讓士兵的指向士兵原型。所以這個(gè)是原型鏈繼承的缺點(diǎn),原因是和指向同一個(gè)地址即父類的。 在理解繼承之前,需要知道 js 的三個(gè)東西: 什么是 JS 原型鏈 this 的值到底是什么 JS 的new 到底是干什么的 想閱讀更多優(yōu)質(zhì)文章...
摘要:的數(shù)據(jù)類型,共有六種。通常,數(shù)值字符串布爾值這三種類型,合稱為原始類型的值,即它們是最基本的數(shù)據(jù)類型,不能再細(xì)分了。運(yùn)算符返回一個(gè)布爾值,表示某個(gè)對(duì)象是否為指定的構(gòu)造函數(shù)的實(shí)例。 以下內(nèi)容摘自阮一峰-JavaScript-標(biāo)準(zhǔn)參考教程 數(shù)據(jù)類型 JavaScript 語言的每一個(gè)值,都屬于某一種數(shù)據(jù)類型。JavaScript 的數(shù)據(jù)類型,共有六種。(ES6 又新增了第七種 Symbo...
摘要:一看這二逼就是周杰倫的死忠粉看看控制臺(tái)輸出,確實(shí)沒錯(cuò)就是對(duì)象。從根本上來說,作用域是基于函數(shù)的,而執(zhí)行環(huán)境是基于對(duì)象的例如全局執(zhí)行環(huán)境即全局對(duì)象。全局對(duì)象全局屬性和函數(shù)可用于所有內(nèi)建的對(duì)象。全局對(duì)象只是一個(gè)對(duì)象,而不是類。 覺得本人寫的不算很爛的話,可以登錄關(guān)注一下我的GitHub博客,博客會(huì)堅(jiān)持寫下去。 今天同學(xué)去面試,做了兩道面試題,全部做錯(cuò)了,發(fā)過來給我看,我一眼就看出來了,因?yàn)?..
摘要:注意客戶端與服務(wù)器日期進(jìn)行傳輸?shù)臅r(shí)候一般都是用大整數(shù)時(shí)間戳進(jìn)行傳輸。 前言 一個(gè)網(wǎng)站的開發(fā)需要要UI、前端、后端三種工程師。現(xiàn)在的企業(yè)在招聘前端工程師的時(shí)候一般都要求其了解或者掌握一些后端的知識(shí)。因此,此文章主要介紹javascript的日期類型,也粗略的介紹一下php的日期類型,以及二者是如何交互數(shù)據(jù)的。 時(shí)間戳 什么是時(shí)間戳 時(shí)間戳是從格林威治時(shí)間1970年1月1日(00:0...
閱讀 2078·2021-11-23 10:13
閱讀 2788·2021-11-09 09:47
閱讀 2737·2021-09-22 15:08
閱讀 3312·2021-09-03 10:46
閱讀 2230·2019-08-30 15:54
閱讀 909·2019-08-28 18:09
閱讀 2429·2019-08-26 18:26
閱讀 2341·2019-08-26 13:48