摘要:運(yùn)算符可以用來(lái)檢測(cè)某個(gè)構(gòu)造函數(shù)的屬性是否存在于另外一個(gè)要檢測(cè)對(duì)象的原型鏈上。使用方法可以獲取到變量的準(zhǔn)確的數(shù)據(jù)類型就能解決基本包裝類型的檢測(cè)錯(cuò)誤和的檢測(cè)不安全。
本文共 1750 字,讀完只需 7 分鐘數(shù)據(jù)類型有哪些?
ECMAScript 的數(shù)據(jù)類型分為簡(jiǎn)單數(shù)據(jù)類型(也被稱為基本數(shù)據(jù)類型,原始數(shù)據(jù)類型):
Undefined
Null
String
Number
Boolean
在 ES6 中新增一個(gè)簡(jiǎn)單數(shù)據(jù)類型 Symbol,所以簡(jiǎn)單數(shù)據(jù)類型總共有 6 個(gè),還有復(fù)雜數(shù)據(jù)類型(也叫作引用數(shù)據(jù)類型):Object。
所有 js 中所有的值最終都將是以上 7 種數(shù)據(jù)類型之一。
基本數(shù)據(jù)類型
基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結(jié)構(gòu)中的,是按值訪問(wèn)的,基本數(shù)據(jù)類型的值不會(huì)變 (值本身無(wú)法被改變)
數(shù)據(jù)之間進(jìn)行的是它們值的比較。
看代碼:
var a,b; a = "jay_chou"; b = a; console.log(a); // jay_chou console.log(b); // jay_chou a = "coldplay"; // 改變 a 的值,并不影響 b 的值 console.log(a); // coldplay console.log(b); // jay_chou
引用數(shù)據(jù)類型
除了基本的數(shù)據(jù)類型外,剩下的就是引用類型,統(tǒng)稱為 Object 類型, 細(xì)分的話,有 Object 類型,Array 類型,Date 類型, Regexp 類型,function, Math 類型;
引用數(shù)據(jù)類型的特點(diǎn):
引用數(shù)據(jù)類型的值保存的是對(duì)象在內(nèi)存中的地址
引用數(shù)據(jù)類型的值是可變的
引用數(shù)據(jù)類型的比較是引用的比較
另外:js 不能直接操作對(duì)象的內(nèi)存空間
比方:
var a = { name: "jay_chou" } var b = a; var c = { name: "jay_chou" } a === b; // true a === c; // false一、為什么要進(jìn)行類型檢測(cè)?
JavaScript 是動(dòng)態(tài)語(yǔ)言,動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言的區(qū)別在于:類型是在編譯時(shí)檢查(靜態(tài))還是在運(yùn)行時(shí)檢查(動(dòng)態(tài))。
基于動(dòng)態(tài)類型的特點(diǎn),如果不注意進(jìn)行類型檢測(cè),JS 很容易在運(yùn)行代碼發(fā)生才發(fā)現(xiàn)報(bào)錯(cuò)。
舉個(gè)列子:
函數(shù)在定義時(shí),參數(shù)可以是任何類型,但是函數(shù)在實(shí)際運(yùn)行的時(shí)候,傳入的實(shí)參可能是其他同事函數(shù)的返回值,也可能是后臺(tái)的返回值,假如不符合代碼邏輯里要求的數(shù)據(jù)類型,那么就會(huì)報(bào)錯(cuò)導(dǎo)致 bug 影響程序運(yùn)行。
因此,我們不光要做類型檢測(cè),也應(yīng)該給自己的函數(shù)注釋好參數(shù)類型和返回值類型,還要和后端定義好接口數(shù)據(jù)類型格式。
當(dāng)比較的兩個(gè)值的類型不同的時(shí)候 == 運(yùn)算符會(huì)進(jìn)行類型轉(zhuǎn)換,但是當(dāng)兩個(gè)值的類型相同的時(shí)候,即使是 == 也相當(dāng)于是 ===;=== 在比較兩個(gè)值的時(shí)候,還會(huì)比較值的數(shù)據(jù)類型。
二、typeof 方式typeof 的返回值總是字符串,字符串的可能值有:
undefined
boolean
number
string
symbol
object
function
typeof 其實(shí)是一元操作符,和 + - * / 一樣,不是一個(gè)函數(shù),進(jìn)行比較的時(shí)候,typeof 后面可以跟(), 也可以不跟。
undefined:
typeof undefined; // undefined
很多庫(kù)因?yàn)榭紤]到 undefined 可能會(huì)被意外重寫(xiě),用 void 0 來(lái)判斷是否是 undefined。
var isUndefined = function (obj) { return obj === void 0; }
MDN 上對(duì) void 詞條的說(shuō)明是:
The void operator evaluates the given expression and then returns undefined.
意思是說(shuō) void 運(yùn)算符能對(duì)給定的表達(dá)式進(jìn)行求值,然后返回 undefined。也就是說(shuō),void 后面你隨便跟上一個(gè)表達(dá)式,返回的都是 undefined,都能完美代替 undefined。
string, number, boolean, symbol, function, object :
typeof "abc"; // stringtypeof 123; // number
typeof NaN; // number
typeof true; // boolean
typeof Symbol(); // symbol
typeof function () {}; // function
typeof {}; // object
null
typeof null; // object!??!
js 中,不同的對(duì)象在底層都表示為二進(jìn)制,在Javascript中二進(jìn)制前三位都為 0 的話會(huì)被檢測(cè)為 Object 類型,null 的二進(jìn)制表示全為0,自然前三位也是 0,所以執(zhí)行 typeof 時(shí)會(huì)返回 "object"。
Array, Date, Regexp, Math:
typeof []; // object
數(shù)組的判斷不考慮兼容性的話,可以用 Array.isArray() 方法進(jìn)行檢測(cè)。
typeof new Date(); // objecttypeof /s/g; // object
typeof Math; // object
typeof new String("foo"); // object?。?!
typeof new Number(123); // object!??!
typeof new Boolean(true); // object!?。?/p>
typeof new Function(""); // function
typeof new Error(); // object
基于以上,基本類型大部分都能被準(zhǔn)確檢測(cè)并返回正確的字符串,并不是所有的類型都能被正確檢測(cè)出來(lái)。所以在實(shí)際應(yīng)用中,避免用基本包裝類型 new Number() 這種方式來(lái)初始化數(shù)據(jù)。
三、instanceof 方式上面說(shuō)到基本包裝類型:new Number(), new Boolean, New String();
它們用 typeof 判斷,會(huì)檢測(cè)成對(duì)象。那針對(duì)基本包裝類型可以用 instanceof 來(lái)判斷。
instanceof 運(yùn)算符可以用來(lái)檢測(cè)某個(gè)構(gòu)造函數(shù)的 prototype 屬性是否存在于另外一個(gè)要檢測(cè)對(duì)象的原型鏈上。
// 定義構(gòu)造函數(shù) function Person(){} var person1 = new Person(); // 因?yàn)?Object.getPrototypeOf(person1) === Person.prototype person1 instanceof Person; // true
現(xiàn)在我們檢測(cè)一下:
var str = new String("abc"); // 基本包裝類型 var strValue = "foo"; strValue instanceof String; // false str instanceof String; // true str instanceof Object; // true [] instanceof Array; // true [] instanceof Object; // true
如果我們修改構(gòu)造函數(shù)的原型后,這個(gè)方法也不怎么靠譜了:
var str = new String("abc"); str.__proto__ = Object.prototype; str instanceof String; // false !!! str instanceof Object; // true四、toString() 方式
ECMAScript 的 Boolean 值、數(shù)字和字符串的原始值的有趣之處在于它們是偽對(duì)象,這意味著它們實(shí)際上具有屬性和方法。
ECMAScript 定義所有對(duì)象都有 toString() 方法,無(wú)論它是偽對(duì)象,還是真對(duì)象。因?yàn)?String 類型屬于偽對(duì)象,所以它一定有 toString() 方法。
使用 Object.prototype.toString 方法, 可以獲取到變量的準(zhǔn)確的數(shù)據(jù)類型.
Object.prototype.toString.call(1); // "[object Number]" Object.prototype.toString.call("1"); // "[object String]" Object.prototype.toString.call(NaN); // "[object Number]" Object.prototype.toString.call(foo); // "[object Function]" Object.prototype.toString.call(Symbol()); // "[object Symbol]" Object.prototype.toString.call([1,2,3]); // "[object Array]" Object.prototype.toString.call(undefined); // "[object Undefined]" Object.prototype.toString.call(null); // "[object Null]" Object.prototype.toString.call(true); // "[object Boolean]" Object.prototype.toString.call(/^s/g); // "[object RegExp]" Object.prototype.toString.call(Math); // "[object Math]" Object.prototype.toString.call(new Error()); // "[object Error]" Object.prototype.toString.call(new Date()); // "[object Date]"
toString 就能解決基本包裝類型的檢測(cè)錯(cuò)誤和 instanceof 的檢測(cè)不安全。
基于 toString 我們可以構(gòu)造很多工具函數(shù)用來(lái)檢測(cè)數(shù)據(jù)類型,這一塊實(shí)現(xiàn)的方案很多,本文就按下不表。
五、應(yīng)用場(chǎng)景js 類型檢測(cè)常見(jiàn)的應(yīng)用場(chǎng)景:
應(yīng)用場(chǎng)景:添加默認(rèn)值
function foo(a, b) { // 方式一 if (typeof b=== "undefined") { b = 0; } // 方式二:不適用foo(10, false)這種情況 b = b || 0; } foo(10);
回調(diào)函數(shù)調(diào)用
function fn(callback) { //typeof callback === "function" ? callback() : null; callback && callback(); } fn(function () { });
還有一個(gè)很常見(jiàn)的應(yīng)用場(chǎng)景當(dāng)然是后臺(tái)返回?cái)?shù)據(jù)的類型的檢測(cè)了。
總結(jié)js 是動(dòng)態(tài)語(yǔ)言,數(shù)據(jù)類型的檢查是在運(yùn)行時(shí)執(zhí)行,為了避免代碼莫名其妙報(bào)錯(cuò),所以做好數(shù)據(jù)類型的檢測(cè)很有必要。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/100069.html
摘要:將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為如果對(duì)象中沒(méi)有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開(kāi)發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫(xiě)這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開(kāi)發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來(lái)理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...
摘要:在之前的文章專題之?dāng)?shù)據(jù)類型和類型檢測(cè)中我有講過(guò),中的數(shù)據(jù)類型分為兩種,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結(jié)構(gòu)中的是按值訪問(wèn),所以不存在深淺拷貝問(wèn)題。 前言 在開(kāi)發(fā)過(guò)程中,偶爾會(huì)遇到這種場(chǎng)景,拿到一個(gè)數(shù)據(jù)后,你打算對(duì)它進(jìn)行處理,但是你又希望拷貝一份副本出來(lái),方便數(shù)據(jù)對(duì)比和以后恢復(fù)數(shù)據(jù)。 那么這就涉及到了 JS 中對(duì)數(shù)據(jù)的深淺拷貝問(wèn)題,所謂深淺拷貝,淺拷貝的意思就是,...
摘要:之面向?qū)ο髮?duì)象類型數(shù)據(jù)類型分六類簡(jiǎn)單類型五種復(fù)雜類型其中也屬于基本類型。 js之面向?qū)ο?OOP) js對(duì)象類型(Object) js數(shù)據(jù)類型分六類,簡(jiǎn)單類型:Undefined,Null,Bollean,Number,String五種,復(fù)雜類型:Object.其中Undefined、Null、Boolean、Number也屬于基本類型。Object、Array和Function則屬...
摘要:專題系列第四篇,講解類型判斷的各種方法,并且跟著寫(xiě)一個(gè)函數(shù)。返回值為表示操作數(shù)類型的一個(gè)字符串。考慮到實(shí)際情況下并不會(huì)檢測(cè)和,所以去掉這兩個(gè)類型的檢測(cè)。 JavaScript專題系列第四篇,講解類型判斷的各種方法,并且跟著 jQuery 寫(xiě)一個(gè) type 函數(shù)。 前言 類型判斷在 web 開(kāi)發(fā)中有非常廣泛的應(yīng)用,簡(jiǎn)單的有判斷數(shù)字還是字符串,進(jìn)階一點(diǎn)的有判斷數(shù)組還是對(duì)象,再進(jìn)階一點(diǎn)的有判...
摘要:專題系列共計(jì)篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖節(jié)流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究專題之函數(shù)組合專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實(shí)現(xiàn)模式需求我們需要寫(xiě)一個(gè)函數(shù),輸入,返回。 JavaScript 專題之從零實(shí)現(xiàn) jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 ext...
閱讀 3740·2021-08-31 09:39
閱讀 1994·2019-08-30 13:14
閱讀 3057·2019-08-30 13:02
閱讀 2894·2019-08-29 13:22
閱讀 2488·2019-08-26 13:54
閱讀 909·2019-08-26 13:45
閱讀 1734·2019-08-26 11:00
閱讀 1108·2019-08-26 10:58