JavaScript數(shù)據(jù)結(jié)構(gòu)常見(jiàn)面試問(wèn)題整理
1.JS有哪些數(shù)據(jù)類型有什么區(qū)別
答:JS共有八大數(shù)據(jù)類型,分別是:String、Number、Boolean、Object、Null、Undefined、Symbol、BigInt。其中Symbol(獨(dú)一無(wú)二不可變)和BigInt(任意精度的數(shù)字)是ES6中新加入的數(shù)據(jù)類型。這些數(shù)據(jù)類型可以分為原始數(shù)據(jù)類型(String、Number、Boolean、Null、Undefined)和引用數(shù)據(jù)類型(Object、數(shù)組、函數(shù)等)。
**區(qū)別:**存儲(chǔ)位置不同 原始數(shù)據(jù)類型直接存儲(chǔ)在棧(stack)中的簡(jiǎn)單數(shù)據(jù)段,占據(jù)空間、大小固定,屬于被頻繁使用的數(shù)據(jù),所以放在棧中存儲(chǔ);引用數(shù)據(jù)類型存儲(chǔ)在堆中的對(duì)象,占據(jù)空間大、大小不固定,如果存儲(chǔ)在棧中,將會(huì)影響程序運(yùn)行的性能。
- 在數(shù)據(jù)結(jié)構(gòu)中,棧中數(shù)據(jù)的存取方式為先進(jìn)后出。
- 堆是一個(gè)優(yōu)先隊(duì)列,是按優(yōu)先級(jí)來(lái)進(jìn)行排序的,優(yōu)先級(jí)可以按照大小來(lái)規(guī)定。
2.數(shù)據(jù)類型檢測(cè)的方式
答:JavaScript有4種方法判斷變量的類型,分別是typeof、instanceof、Object.prototype.toString.call()(對(duì)象原型鏈判斷方法)、 constructor (用于引用數(shù)據(jù)類型) 。typeof:常用于判斷基本數(shù)據(jù)類型,對(duì)于引用數(shù)據(jù)類型除了function返回’function‘,其余全部返回’object’。 instanceof:主要用于區(qū)分引用數(shù)據(jù)類型,檢測(cè)方法是檢測(cè)的類型在當(dāng)前實(shí)例的原型鏈上,用其檢測(cè)出來(lái)的結(jié)果都是true,不太適合用于簡(jiǎn)單數(shù)據(jù)類型的檢測(cè),檢測(cè)過(guò)程繁瑣且對(duì)于簡(jiǎn)單數(shù)據(jù)類型檢測(cè)不出來(lái)。 constructor:用于檢測(cè)所有數(shù)據(jù)類型,檢測(cè)方法是獲取實(shí)例的構(gòu)造函數(shù)判斷和某個(gè)類是否相同,如果相同就說(shuō)明該數(shù)據(jù)是符合那個(gè)數(shù)據(jù)類型的,這種方法不會(huì)把原型鏈上的其他類也加入進(jìn)來(lái),避免了原型鏈的干擾。 Object.prototype.toString.call():適用于所有類型的判斷檢測(cè),檢測(cè)方法是Object.prototype.toString.call(數(shù)據(jù)) 返回的是該數(shù)據(jù)類型的字符串。 這四種判斷數(shù)據(jù)類型的方法中,各種數(shù)據(jù)類型都能檢測(cè)且檢測(cè)精準(zhǔn)的就是Object.prototype.toString.call()這種方法。
加分回答 instanceof的實(shí)現(xiàn)原理:驗(yàn)證當(dāng)前類的原型prototype是否會(huì)出現(xiàn)在實(shí)例的原型鏈__proto__上,只要在它的原型鏈上,則結(jié)果都為true。因此,instanceof 在查找的過(guò)程中會(huì)遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,找到返回true,未找到返回false。 Object.prototype.toString.call()原理:Object.prototype.toString 表示一個(gè)返回對(duì)象類型的字符串,call()方法可以改變this的指向,那么把Object.prototype.toString()方法指向不同的數(shù)據(jù)類型上面,返回不同的結(jié)果
(1)typeof:返回?cái)?shù)據(jù)的類型,但是數(shù)組、null、對(duì)象、函數(shù),都只能返回object,所以typeof并不能區(qū)分出處理function的其他object中的幾種不同類型。
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof []); // object
console.log(typeof function(){}); // function
console.log(typeof {}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object
衍生問(wèn)題:為什么typeof null 是obect ?
原因是:在JS的第一個(gè)版本中,所有值都存儲(chǔ)在32位的單元中,每個(gè)單元包含一個(gè)小的類型標(biāo)簽,以及當(dāng)前要存儲(chǔ)的真實(shí)數(shù)據(jù),類型標(biāo)簽包括000(object)、1(int)、010(double)、100(string)、110(boolean)。而null的機(jī)器碼全是0,所以被認(rèn)為是object。
(2)instanceof:可以判斷instanceof后面的類型是否正確,返回true / false,內(nèi)部的運(yùn)行機(jī)制是看能不能在原型鏈中找到該類型的原型。但是instanceof只能判斷出引用數(shù)據(jù)類型,并且可以區(qū)分出數(shù)組、函數(shù)等,卻不能判斷基本數(shù)據(jù)類型。
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
(3)constructor可以判斷數(shù)據(jù)類型,還可以訪問(wèn)對(duì)象的構(gòu)造函數(shù)。constructor可以把object分開(kāi)來(lái)判斷。分為(Array、Function、object)
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
(4)Object.prototype.toString.call():使用Object對(duì)象的原型方法toString來(lái)判斷數(shù)據(jù)類型
var a = Object.prototype.toString;
console.log(a.call(2)); //[object Number]
console.log(a.call(true)); //[object Boolean]
console.log(a.call('str')); //[object String]
console.log(a.call([])); //[object Array]
console.log(a.call(function(){})); //[object Function]
console.log(a.call({})); //[object Object]
console.log(a.call(undefined)); //[object Undefined]
console.log(a.call(null)); //[object Null]
3.判斷是否是數(shù)組的方法
var b = new Array(); console.log(b instanceof Array); //true console.log(Object.prototype.toString.call(b)); //[object Array] console.log(Array.isArray(b)); //true console.log(b.constructor===Array); //true console.log(b.__proto__===Array.prototype); //true console.log(Array.prototype.isPrototypeOf(b)); //true
4.null和undefined的區(qū)別
答:undefind 是全局對(duì)象的一個(gè)屬性,當(dāng)一個(gè)變量沒(méi)有被賦值或者一個(gè)函數(shù)沒(méi)有返回值或者某個(gè)對(duì)象不存在某個(gè)屬性卻去訪問(wèn)或者函數(shù)定義了形參但沒(méi)有傳遞實(shí)參,這時(shí)候都是undefined。undefined通過(guò)typeof判斷類型是’undefined’。undefined == undefined undefined === undefined 。 null代表對(duì)象的值未設(shè)置,相當(dāng)于一個(gè)對(duì)象沒(méi)有設(shè)置指針地址就是null。null通過(guò)typeof判斷類型是’object’。null === null null == null null == undefined null !== undefined undefined 表示一個(gè)變量初始狀態(tài)值,而 null 則表示一個(gè)變量被人為的設(shè)置為空對(duì)象,而不是原始狀態(tài)。在實(shí)際使用過(guò)程中,不需要對(duì)一個(gè)變量顯式的賦值 undefined,當(dāng)需要釋放一個(gè)對(duì)象時(shí),直接賦值為 null 即可。 讓一個(gè)變量為null,直接給該變量賦值為null即可。typeof null是object。
undefined == null //true undefined === null //false undefined !== null //true
5.手寫instanceof方法
function myInstanceof(left,right){
let proto = Object.getPrototypeOf(left)
let prototype = right.prototype;
while(true){
if(!proto) return false
if(proto === prototype) return true
proto = Object.getPrototypeOf(proto)
}
}
console.log(myInstanceof("",Array)); //false
console.log(myInstanceof([1,2,3],Array)); //true6.為什么0.1+0.2 !==0.3
答:首先要知道小數(shù)是如何轉(zhuǎn)為二進(jìn)制的,整數(shù)部分就是不斷除2取余,小數(shù)部分就是乘二取整,超過(guò)1以后還是用小數(shù)部分乘,如下所示:
//不斷的乘以二然后拿掉整數(shù)部分,直到積為0。
//但是結(jié)果是不可能為0的,所以是循環(huán)的
0.1 * 2 = 0.2 => 0
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0
…
因此,0.1的二進(jìn)制是0.0001 1001 1001 1001…無(wú)限循環(huán),0.2的二進(jìn)制是0.0011 0011 0011 0011…無(wú)限循環(huán),所以0.3的二進(jìn)制就是0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100,轉(zhuǎn)換為十進(jìn)制就是0.300000004,這就是精度丟失問(wèn)題,所以0.1+0.2 !== 0.3??梢杂胻oFixed(1)來(lái)解決,但也要注意,toFixed()返回的類型是String。
7.isNaN和Number.isNaN函數(shù)的區(qū)別
- isNaN接受參數(shù)后,會(huì)嘗試將這個(gè)參數(shù)轉(zhuǎn)換為數(shù)值,任何不能轉(zhuǎn)換的都會(huì)返回true,因此,非數(shù)字值傳入也會(huì)返回true,會(huì)影響NaN的判斷。
- Number.isNaN會(huì)首先判斷傳入?yún)?shù)是否是數(shù)字,如果是數(shù)字再繼續(xù)判斷是否為NaN,不會(huì)進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)換,更加準(zhǔn)確。
console.log(isNaN(NaN)) //true
console.log(isNaN("123")); //false
console.log(isNaN("NaN")); //true
console.log(Number.isNaN(NaN)); //true
console.log(Number.isNaN("123")); //false
console.log(Number.isNaN("NaN")); //false8.==操作符的強(qiáng)制類型轉(zhuǎn)換規(guī)則
(1)類型相同的話就直接比較;
(2)類型不同的話,會(huì)進(jìn)行類型轉(zhuǎn)換;
(3)先判斷是不是null 和 undefined,是的話就返回true;
(4)判斷是否是string 和 number,string --> number;
(5)如果有一方是boolean,那么boolean --> number;
(6)如果一方是object,另一方是string number symbol,把object–> 原始類型。
console.log(NaN == NaN); //false console.log(null instanceof Object); //false 因?yàn)閚ull是原型鏈的頂端了,而instanceof是根據(jù)Object.getPrototypeof()實(shí)現(xiàn)的,找不到他的父類了 console.log(null == null); //true console.log(false == ""); //true console.log(undefined == false); //false
9.強(qiáng)制轉(zhuǎn)換的規(guī)則
(1)其他值–>字符串:Null、Undefined、Boolean、Number、Symbol都是直接轉(zhuǎn)換為字符串,加上雙引號(hào),對(duì)于普通對(duì)象來(lái)說(shuō),一般會(huì)用toString()轉(zhuǎn)換為內(nèi)部屬性[[Class]]的值;
(2)其他值–>數(shù)字值:①Undefined類型的值轉(zhuǎn)換為NaN,Null類型轉(zhuǎn)換為0,true為1,false為0,String如果包含非數(shù)字就為NaN,否則為數(shù)字,空字符串為0,Symbol會(huì)報(bào)錯(cuò);
(3)其他值–>布爾值:false值包括(undefined,null,false,+0,-0,NaN,“”),其他值都是真值。
10.Object.is()與比較操作符===和==的區(qū)別
答:==在進(jìn)行判斷時(shí),如果兩邊類型不一致,會(huì)進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換以后再比較;===如果兩邊類型不一致,就不會(huì)進(jìn)行強(qiáng)制類型轉(zhuǎn)換,直接返回false;Object.is()一般情況下和三等號(hào)相同,但是-0和+0不再相等,兩個(gè)NaN是相等的。
到此這篇關(guān)于JavaScript數(shù)據(jù)結(jié)構(gòu)常見(jiàn)面試問(wèn)題整理的文章就介紹到這了,更多相關(guān)JavaScript數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript樹(shù)形數(shù)據(jù)結(jié)構(gòu)處理
- JavaScript隊(duì)列數(shù)據(jù)結(jié)構(gòu)詳解
- JavaScript數(shù)據(jù)結(jié)構(gòu)與算法
- JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之棧詳解
- Javascript數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列詳解
- ?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建(2)
- JavaScript?數(shù)據(jù)結(jié)構(gòu)之字典方法
- JavaScript?數(shù)據(jù)結(jié)構(gòu)之集合創(chuàng)建(2)
- JavaScript?數(shù)據(jù)結(jié)構(gòu)之集合創(chuàng)建(1)
相關(guān)文章
JS鼠標(biāo)滑過(guò)圖片時(shí)切換圖片實(shí)現(xiàn)思路
在瀏覽網(wǎng)頁(yè)時(shí)會(huì)看到這樣的效果:當(dāng)鼠標(biāo)滑過(guò)一張圖片后,這張圖片切換為了另外的一張圖片,下面為大家介紹下具體是如何實(shí)現(xiàn)的,感興趣的朋友不要錯(cuò)過(guò)2013-09-09
javascript設(shè)計(jì)簡(jiǎn)單的秒表計(jì)時(shí)器
這篇文章主要介紹了javascript設(shè)計(jì)簡(jiǎn)單的秒表計(jì)時(shí)器,該秒表將包括兩個(gè)按鈕和一個(gè)用于顯示時(shí)間的文本框,當(dāng)單擊開(kāi)始按鈕時(shí)開(kāi)始計(jì)時(shí),最小單位為0.01秒,此時(shí)再次單擊按鈕則停止計(jì)時(shí),文本框顯示經(jīng)過(guò)的時(shí)間,需要的朋友可以參考下2015-11-11
除Console.log()外更多的Javascript調(diào)試命令
本篇文章給大家介紹了除Console.log()外更多的Javascript調(diào)試命令,方便大家更多環(huán)境下的JS調(diào)試,學(xué)習(xí)下吧。2018-01-01
基于JS實(shí)現(xiàn)textarea中獲取動(dòng)態(tài)剩余字?jǐn)?shù)的方法
這篇文章主要介紹了基于JS實(shí)現(xiàn)textarea中獲取動(dòng)態(tài)剩余字?jǐn)?shù)的方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-05-05
JavaScript中this的學(xué)習(xí)筆記及用法整理
在本篇文章里小編給大家整理的是關(guān)于JavaScript中this的使用以及代碼實(shí)例,需要的朋友們學(xué)習(xí)下。2020-02-02
uniapp實(shí)現(xiàn)審批流程的具體操作步驟
這篇文章主要介紹了uniapp實(shí)現(xiàn)審批流程的具體操作方法,實(shí)現(xiàn)思路大概是需要要定義一個(gè)變量,記錄當(dāng)前激活的步驟,通過(guò)數(shù)組的長(zhǎng)度來(lái)循環(huán)數(shù)據(jù),如果有就采用3元一次進(jìn)行選擇,具體實(shí)現(xiàn)步驟跟隨小編一起看看吧2024-03-03
layui實(shí)現(xiàn)checkbox的目錄樹(shù)tree的例子
今天小編就為大家分享一篇layui實(shí)現(xiàn)checkbox的目錄樹(shù)tree的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09

