<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
首先介紹一下JavaScript中的八大基本型別
除物件型別(object)以外的其它任何型別定義的不可變的值(值本身無法被改變)。例如(與 C 語言不同),JavaScript 中字串是不可變的(譯註:如,JavaScript 中對字串的操作一定返回了一個新字串,原始字串並沒有被改變)。我們稱這些型別的值為“原始值”。 —— MDN
(1)布林型別(Boolean)
布林表示一個邏輯實體,可以有兩個值:true
和false
、
(2)Null型別
null
(3)Undefined型別
undefined
是全域性物件的一個屬性。也就是說,它是全域性作用域的一個變數。undefined
的最初值就是原始資料型別undefined。console.log(undefined in window) // true let a; console.log(a) // undefined
function f() { } console.log(f()) // undefined
(4)數位型別(Number)
Infinity
(或者+Infinity)-Infinity
// 注意:Number.MIN_VALUE(5e-324)— Number.MAX_VALUE(1.7976931348623157e+308) 是可以表示的正值範圍 console.log(Number.MIN_VALUE); // 5e-324 console.log(Number.MAX_VALUE); // 1.7976931348623157e+308 console.log(1e310); // Infinity console.log(-1e310); // -Infinity console.log(1e-330); // 0 console.log(-1e-330); // 0
NaN
(非數值,Not-a-Number)。not-a-number:
NaN
是一個全域性物件的屬性。NaN
屬性的初始值就是 NaN,和Number.NaN
的值一樣。
(5)BigInt
// 數位型別安全整數限制 console.log(Number.MIN_SAFE_INTEGER) // -9007199254740991 console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
n
或呼叫建構函式來建立的。// 建構函式建立 // BigInt() 不與 new 運運算元一起使用。 let a = BigInt(1); // 末尾附加字母n建立 let b = 1n; console.log(a) // 1n console.log(b) // 2n
BigInt
不能與數位相互運算。否則,將丟擲TypeError
。console.log(1 + 1n); //Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
(6)字串型別(String)
JavaScript 的字串型別用於表示文字資料。它是一組 16 位的無符號整數值的“元素”。在字串中的每個元素佔據了字串的位置。第一個元素的索引為0
,下一個是索引1
,依此類推。字串的長度是它的元素的數量。
(7)符號型別(Symbols)
for( ... in ...)
” 中作為成員出現,也因為這個屬性是匿名的,它同樣不會出現在 “Object.getOwnPropertyNames()
” 的返回陣列裡。這個屬性可以通過建立時的原始 symbol 值存取到,或者通過遍歷 “Object.getOwnPropertySymbols()
” 返回的陣列。在之前的程式碼範例中,通過儲存在變數 myPrivateMethod
的值可以存取到物件屬性。物件型別(Object)
在電腦科學中, 物件(object)是指記憶體中的可以被識別符號參照的一塊區域。
在 JavaScript 中,物件可以被看作是一組屬性的集合。用物件字面量語法來定義一個物件時,會自動初始化一組屬性。而後,這些屬性還可以被新增和移除。
物件擁有兩種屬性:
a、資料屬性
b、存取器屬性
JavaScript中提供了很多內建物件,可參考MDN官方檔案。
(1)原始資料型別:
基礎型別儲存在棧記憶體,被參照或拷貝時,會建立一個完全相等的變數;佔據空間小、大小固定,屬於被頻繁使用資料,所以放入棧中儲存。
(2)參照資料型別:
參照型別儲存在堆記憶體,儲存的是地址,多個參照指向同一個地址,這裡會涉及一個“共用”的概念;佔據空間大、大小不固定。參照資料型別在棧中儲存了指標,該指標指向堆中該實體的起始地址。當直譯器尋找參照值時,會首先檢索其在棧中的地址,取得地址後從堆中獲得實體。
所以,在 JavaScript 中,原始型別的賦值會完整複製變數值,而參照型別的賦值是複製參照地址。
typeof
操作符返回一個字串,表示未經計算的運算元的型別。
語法:
// operand:一個表示物件或原始值的表示式,其型別將被返回 typeof operand typeof(operand)
返回值:
"undefined" "object" "boolean" "number" "bigint" "string" "symbol" "function" "object"
(1)不同資料型別的 typeof 值
// 歷史遺留問題 console.log(typeof null); // object // Undefined 型別typeof值為 undefined console.log(typeof undefined); // undefined // 未定義的變數 typeof值也為 undefined console.log(typeof a); // undefined // 非數值 console.log(typeof NaN); // number // 無窮大 console.log(typeof Infinity); // number // 除 Null 和 Undefined 之外的原始資料型別 typeof 值都是對應的型別 console.log(typeof true); // boolean console.log(typeof 2); // number console.log(typeof 2n); // bigint console.log(typeof BigInt(1)); // bigint console.log(typeof 'str'); // string console.log(typeof Symbol(1)); // symbol console.log(typeof Boolean(true)); // boolean console.log(typeof Number(1)); // number console.log(typeof String('str')); // string // 基本包裝型別 console.log(typeof new Boolean(true)); // object console.log(typeof new Number(1)); // object console.log(typeof new String('str')); // object // 字面量 console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof /1/); // object // 除了 Function 物件範例, typeof值都是 object console.log(typeof new Object()); // object console.log(typeof new Array()); // object console.log(typeof new Map()); // object console.log(typeof new Set()); // object console.log(typeof new Date()); // object console.log(typeof new RegExp()); // object console.log(typeof Math); // object // Function 物件範例, typeof值為 function console.log(typeof new Function()); // function console.log(typeof Function); // function console.log(typeof Array); // function console.log(typeof Set); // function console.log(typeof Date); // function console.log(typeof RegExp); // function console.log(typeof Object); // function
(2) typeof null === 'object' 的原因
“typeof null”錯誤是 JavaScript 第一版的遺留物。在這個版本中,值儲存在 32 位單元中,由一個小型標籤(1-3 位)和值的實際資料組成。型別標籤儲存在單元的低位中。
其中有五個:
也就是說,最低位是任一位,那麼型別標籤只有一位長。或者為零,則型別標籤的長度為三位,為四種型別提供兩個額外的位。
有兩個值是特殊的:
所以 typeof 認為 null 是一個 object
(3)物件型別 typeof 返回值的理解
針對物件型別,個人理解 的是:
(4)關於 typeof Boolean(true) 和 typeof new Boolean(true)不同的原因
// 簡單呼叫Boolean() 函數 console.log(Boolean(true)); // true // 建立一個Boolean物件 console.log(new Boolean(true)); // Boolean {true}
Boolean(true) 的返回值就是Boolean型別的資料,newBoolean(true)返回的是一個Boolean物件。
(5)總結
instanceof
運運算元用於檢測建構函式的 prototype
屬性是否出現在某個範例物件的原型鏈上
語法:
// object:某個範例物件 // constructor:某個建構函式 object instanceof constructor
(1)相關例子
// instanceof 右邊是一個建構函式,所以undefined 和 null 不能使用instanceof,下面兩條語句執行會報錯 // console.log(undefined instanceof Undefined); // console.log(null instanceof Null); // 對於原始資料型別無法檢測 console.log(2 instanceof Number); // false console.log(1n instanceof BigInt); // false console.log(true instanceof Boolean); // false console.log('str' instanceof String); // false console.log(Symbol(1) instanceof Symbol); // false // 可以檢測內建物件型別 console.log([] instanceof Array); // true console.log(function(){} instanceof Function); // true console.log({} instanceof Object); // true console.log(/1/ instanceof RegExp); // true // 所有函數物件範例原型鏈上都存在Function console.log(Array instanceof Function); // true console.log(Set instanceof Function); // true console.log(Map instanceof Function); // true console.log(Date instanceof Function); // true console.log(RegExp instanceof Function); // true console.log(Function instanceof Function); // true console.log(Object instanceof Function); // true // Object 是所有範例物件原型鏈的盡頭 console.log(Array instanceof Object); // true console.log(Set instanceof Object); // true console.log(Map instanceof Object); // true console.log(Date instanceof Object); // true console.log(RegExp instanceof Object); // true console.log(Function instanceof Object); // true console.log(Object instanceof Object); // true function foo() {} // foo 是 Function的一個範例 console.log(foo instanceof Object); // true console.log(foo instanceof Function); // true // new foo() 是 foo 的一個範例 console.log(new foo() instanceof foo); // true console.log(new foo() instanceof Object); // true console.log(new foo() instanceof Function); // false // foo() 返回的是undefined console.log(foo() instanceof Object); // false console.log(foo() instanceof Function); // false
(2) 當建構函式的proptotype發生改變時,instanceof 結果可能會出錯
function foo() {} let f = new foo(); console.log(f instanceof foo) // true // foo 原型發生改變 foo.prototype = Array.prototype; console.log(f instanceof foo); // false
(3)手動實現 instanceof
function myInstanceof(left, right) { // 獲得建構函式的原型 let prototype = right.prototype // 獲得物件的原型 left = left.__proto__ // 判斷物件的型別是否等於型別的原型 while (true) { // 原型鏈的盡頭是 null,說明範例物件的原型鏈遍歷結束 if (left === null) return false if (prototype === left) return true left = left.__proto__ } }
上述手動實現只是實現了基本功能,但與原生instanceof仍然存在差別,例如:
// 檢驗right 是否是一個物件(Object) if (right is not Object){ throw new TypeError(" Uncaught TypeError: Right-hand side of 'instanceof' is not Object") } // 檢驗 right 是否可被呼叫 if (right is not callable) { throw new TypeError(" Uncaught TypeError: Right-hand side of 'instanceof' is not callable") }
console.log(_instanceof('str', String)) // true
有關instanceof 原理,可繼續深入瞭解原型鏈相關知識點。
(4)總結
例如:
console.log([] instanceof Array); // true console.log([] instanceof Object); // true
所以 instanceof 用於判斷資料型別也存在弊端。
(1)相關例子
// null 和 undefined 沒有建構函式 onsole.log(null.constructor) // TypeError onsole.log(undefined.constructor) // TypeError // 原始資料型別 console.log((2).constructor === Number); // true console.log((2n).constructor === BigInt); // true console.log((true).constructor === Boolean); // true console.log(('str').constructor === String); // true console.log(Symbol(1).constructor === Symbol); // true // 字面量 console.log(([]).constructor === Array); // true console.log((/1/).constructor === RegExp); // true console.log((function() {}).constructor === Function); // true console.log(({}).constructor === Object); // true // JavaScript中的內建函數物件的建構函式為 Function console.log(Array.constructor === Function); // true console.log(String.constructor === Function); // true console.log(Function.constructor === Function); // true console.log(Object.constructor === Function); // true // JavaScript中的內建普通物件的建構函式為 Object console.log(Math.constructor === Object); // true console.log(JSON.constructor === Object); // true console.log(Atomics.constructor === Object); // true console.log(Intl.constructor === Object); // true console.log(Reflect.constructor === Object); // true console.log(WebAssembly.constructor === Object); // true
(2)如果建立一個物件前修改建構函式的原型,會導致constructor不可靠
function Fn(){}; Fn.prototype=new Array(); var f=new Fn(); console.log(f.constructor===Fn); // false console.log(f.constructor===Array); // true
(3)總結
所以 constructor 判斷資料型別也存在弊端。
(1)Object.prototype.toString()
每個物件都有一個
toString()
方法,當該物件被表示為一個文字值時,或者一個物件以預期的字串方式參照時自動呼叫。預設情況下,toString()
方法被每個Object
物件繼承。如果此方法在自定義物件中未被覆蓋,toString()
返回 "[object type]" ,其中type
是物件的型別 —— MDN
(2) Object.prototype.toString.call() 範例
// 原始資料型別 console.log(Object.prototype.toString.call(undefined)) // [object Undefined] console.log(Object.prototype.toString.call(null)) // [object Null] console.log(Object.prototype.toString.call(1)) // [object Number] console.log(Object.prototype.toString.call(1n)) // [object BigInt] console.log(Object.prototype.toString.call(true)) // [object Boolean] console.log(Object.prototype.toString.call('str')) // [object String] console.log(Object.prototype.toString.call(Symbol(1))) // [object Symbol] // 字面量 console.log(Object.prototype.toString.call({})) // [object object] console.log(Object.prototype.toString.call([])) // [object Array] console.log(Object.prototype.toString.call(/1/)) // [object RegExp] console.log(Object.prototype.toString.call(NaN)) // [object Number] console.log(Object.prototype.toString.call(Infinity)) // [object Number] console.log(Object.prototype.toString.call(globalThis)) // [object Window] // 內建函數物件範例 console.log(Object.prototype.toString.call(new Array())) // [object Array] console.log(Object.prototype.toString.call(new Map())) // [object Map] console.log(Object.prototype.toString.call(new Set())) // [object Set] console.log(Object.prototype.toString.call(new Date())) // [object Date] console.log(Object.prototype.toString.call(new Function())) // [object Function] // 內建普通物件本身 console.log(Object.prototype.toString.call(Math)) // [object Math] console.log(Object.prototype.toString.call(JSON)) // [object JSON] console.log(Object.prototype.toString.call(Reflect)) // [object Reflect] // 內建函數物件本身 console.log(Object.prototype.toString.call(Array)) // [object Function] console.log(Object.prototype.toString.call(Map)) // [object Function] console.log(Object.prototype.toString.call(Function)) // [object Function] console.log(Object.prototype.toString.call(Object)) // [object Function] // 瀏覽器全域性物件 console.log(Object.prototype.toString.call(document)) // [object HTMLDocument] console.log(Object.prototype.toString.call(window)) // [object Window] // 自定義建構函式 function Foo() {} f = new Foo(); console.log(Object.prototype.toString.call(f)) // [object object] console.log(Object.prototype.toString.call(Foo)) // [object Function]
(3)基於Object.prototype.toString.call()實現資料型別判斷
function getType(obj){ let type = typeof obj; if (type !== "object") { // 先進行typeof判斷,如果是基礎資料型別,直接返回 return type; } // 對於typeof返回結果是object的,再進行如下的判斷,正則返回結果 return Object.prototype.toString.call(obj).replace(/^[object (S+)]$/, '$1'); // 注意正則中間有個空格 }
(4)總結
Object.prototype.toString.call() 能準確判斷資料型別。
到此這篇關於分享JavaScript 型別判斷的幾種方法的文章就介紹到這了,更多相關JavaScript 型別判斷內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45