前端面試梳理(一):基礎(chǔ)知識點

前端面試梳理(一):基礎(chǔ)知識點

原始類型

涉及面試題:基礎(chǔ)數(shù)據(jù)類型有哪些损谦?null是對象?

基礎(chǔ)數(shù)據(jù)類型有哪些岳颇?

在js中基礎(chǔ)數(shù)據(jù)類型:

  • String
  • Number
  • Boolean
  • undefined
  • null
  • Symbol

原始數(shù)據(jù)存儲的都是值照捡,是沒有方法的,比如undefined.toString().
那為什么會存在“123”.toString呢话侧?
原因:當(dāng)你對基礎(chǔ)數(shù)值調(diào)用方法的時候栗精,發(fā)生了隱式轉(zhuǎn)化,已經(jīng)被轉(zhuǎn)化成了Number對象了。“123”.toString() == Number("123").toString()

null是對象瞻鹏?

答案:不是悲立。
也許你會反駁到 typeof null 會輸出‘Object’。但是這是js設(shè)計之初就存在的bug新博,因為typeof 判斷對象的方式是直接變量判斷內(nèi)存的是否是以000開頭的速蕊,而null在內(nèi)存中的地址是全為0毯炮,所有才會出現(xiàn)這樣的問題。

number也是問題大戶

0.1+0.2 != 0.3 // true
1111111111111111 == 11111111111111112 // true

什么呢腥放?
先說原因,因為 JS 采用 IEEE 754 雙精度版本(64位)议泵,并且只要采用 IEEE 754 的語言都有該問題驮配。
IEEE754是怎么表示的:

  s   eeeeeeeeeee   fff...ffff
|-1-|-     11    -|-    52    -|

意義

  • 1位用來表示符號位
  • 11位用來表示指數(shù)
  • 52位表示尾數(shù)

那么0.1在二進(jìn)制是怎么表示?

// (0011) 表示循環(huán)
0.1 >> 0.0001 1001 1001 1001…(1001無限循環(huán))
0.2 >> 0.0011 0011 0011 0011…(0011無限循環(huán))

其實不僅僅0.1,還有0.2同诫,111111111111111111等等很多數(shù)字都是以循環(huán)體存在的粤策。這本來是沒什么問題的,但是js采用的IEEE754雙精度浮點(64)標(biāo)準(zhǔn)误窖,輸出十進(jìn)制進(jìn)行四舍五入了叮盘,但是二進(jìn)制只有 0 和 1 兩個,于是變?yōu)?0 舍 1 入霹俺。這即是計算機中部分浮點數(shù)運算時出現(xiàn)誤差柔吼。

0.100000000000000002 === 0.1 // true
0.200000000000000002 === 0.2 // true
0.1 + 0.2 === 0.30000000000000004 // true

但是你可能又會問:console.log("0.1") 為什么不會輸出 “0.100000000000000002”?
因為在輸入內(nèi)容的時候,二進(jìn)制被轉(zhuǎn)換為了十進(jìn)制丙唧,十進(jìn)制又被轉(zhuǎn)換為了字符串愈魏,在這個轉(zhuǎn)換的過程中發(fā)生了取近似值的過程.

// 所以輸出 0.1
console.log(0.100000000000000002) // 0.1

那么如何處理這個問題呢?

// 小數(shù)用toFixed
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 // true
// 大整數(shù)用BigInt
BigInt("11111111111111111") + 0n // 11111111111111111n

對象類型

涉及面試題:對象類型和基礎(chǔ)類型的不同?函數(shù)參數(shù)是對象會發(fā)生什么問題培漏?

對象類型和基礎(chǔ)類型的區(qū)別

  • 內(nèi)存的分配不同

    • 基本數(shù)據(jù)類型存儲在棧中溪厘。
    • 復(fù)雜數(shù)據(jù)類型存儲在堆中,棧中存儲的變量牌柄,是指向堆中的引用地址畸悬。
  • 訪問機制不同

    • 基本數(shù)據(jù)類型是按值訪問
    • 復(fù)雜數(shù)據(jù)類型按引用訪問,JS不允許直接訪問保存在堆內(nèi)存中的對象珊佣,在訪問一個對象時蹋宦,首先得到的是這個對象在棧內(nèi)存中的地址,然后再按照這個地址去獲得這個對象中的值咒锻。
  • 復(fù)制變量時不同(a=b)

    • 基本數(shù)據(jù)類型:a=b;是將b中保存的原始值的副本賦值給新變量a冷冗,a和b完全獨立,互不影響
    • 復(fù)雜數(shù)據(jù)類型:a=b;將b保存的對象內(nèi)存的引用地址賦值給了新變量a;a和b指向了同一個堆內(nèi)存地址惑艇,其中一個值發(fā)生了改變贾惦,另一個也會改變。

下面的輸出結(jié)果:

var a = {n: 1};
var b = a;
a.x = a = {n: 2};

a.x     // 輸出敦捧?
b.x     // 輸出

答案: a.x // --> undefined b.x // --> {n: 2}

  • 1须板、優(yōu)先級。.的優(yōu)先級高于=兢卵,所以先執(zhí)行a.x习瑰,堆內(nèi)存中的{n: 1}就會變成{n: 1, x: undefined},改變之后相應(yīng)的b.x也變化了秽荤,因為指向的是同一個對象甜奄。
  • 2、賦值操作是從右到左窃款,所以先執(zhí)行a = {n: 2}课兄,a的引用就被改變了,然后這個返回值又賦值給了a.x晨继,需要注意的是這時候a.x是第一步中的{n: 1, x: undefined}那個對象烟阐,其實就是b.x,相當(dāng)于b.x = {n: 2}

typeof vs instanceof

涉及面試題:typeof 是否能正確判斷類型紊扬?instanceof 能正確判斷對象的原理是什么蜒茄?

  • typeof 對于基礎(chǔ)類型來說,除了 null 都可以顯示正確的類型
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'

typeOf對于對象類型就無法起到作用了:

typeof {} // object
typeof [] // object
typeof String // function
  • instanceof 可以正確的判斷對象的類型餐屎,因為內(nèi)部機制是通過判斷對象的原型鏈中是不是能找到類型的 prototype
function myInstanceof(left, right) {
  let prototype = right.prototype
  left = left.__proto__
  while (true) {
    if (left === null || left === undefined)
      return false
    if (prototype === left)
      return true
    left = left.__proto__
  }
}

原理:

  • 首先獲取類型的原型
  • 然后獲得對象的隱式原型
  • 然后一直循環(huán)判斷對象的隱式原型是否等于類型的原型檀葛,直到對象隱式原型為 null,因為原型鏈最終為 null

那么如何靠譜的區(qū)分對象呢腹缩?

Object.prototype.toString.call([])    // "[object Array]"
Object.prototype.toString.call({})    //"[object Object]"
Object.prototype.toString.call(/\./)  // "[object RegExp]"

類型轉(zhuǎn)換

涉及面試題:該知識點常在筆試題

常見的隱式轉(zhuǎn)化有三種:

  • 轉(zhuǎn)化為String
  • 轉(zhuǎn)化為Number
  • 裝化為Boolean

轉(zhuǎn)Boolean:

undefined屿聋,null空扎,“”,0润讥,+0勺卢,-0,NaN轉(zhuǎn)化為發(fā)垃圾象对,其余都是true

對象轉(zhuǎn)原始類型

  • 1.對象在轉(zhuǎn)換類型的時候,會調(diào)用內(nèi)置的 [[ToPrimitive]] 函數(shù)宴抚,對于該函數(shù)來說勒魔,算法邏輯一般來說如下:
  • 2.是否為原始類型了,如果是就無需轉(zhuǎn)化菇曲,如果不是就往下
  • 3.調(diào)用valueOf()冠绢,如果轉(zhuǎn)換為基礎(chǔ)類型,就返回轉(zhuǎn)換的值常潮,如果不是就往下
  • 4.調(diào)用 x.toString()弟胀,如果轉(zhuǎn)換為基礎(chǔ)類型,就返回轉(zhuǎn)換的值喊式,如果不是就往下
  • 5.如果都沒有返回原始類型孵户,就會報錯

當(dāng)然你也可以重寫 Symbol.toPrimitive ,該方法在轉(zhuǎn)原始類型時調(diào)用優(yōu)先級最高岔留。

let a = {
  valueOf() {
    return 0
  },
  toString() {
    return '1'
  },
  [Symbol.toPrimitive]() {
    return 2
  }
}
1 + a // => 3

常見面試題:

a==1 && a==2 && a==3 ?

// 1.利用隱式類型轉(zhuǎn)換
const a = {
    [Symbol.toPrimitive]: (() => {
        let i =1;
        return () => i++;
    })()
}
const a = {
    i: 1,
    valueOf: () => {
        return a.i++;
    }
}
// 2.利用數(shù)據(jù)劫持(Proxy/Object.defineProperty)
let i = 1;
let a = new Proxy({}, {
    i:1,
    get: function () {
        return () => this++
    }
})
// 使用數(shù)組夏哭, 數(shù)組的同toString默認(rèn)調(diào)用的join
let a = [1,2,3]
a.join = a.shift

四則運算符轉(zhuǎn)化

- 運算中其中一方為字符串,那么就會把另一方也轉(zhuǎn)換為字符串
- 如果一方不是字符串或者數(shù)字献联,那么會將它轉(zhuǎn)換為數(shù)字或者字符串
- ```js
        1 + '1' // '11'
        true + true // 2
        4 + [1,2,3] // "41,2,3"
    ```
- 

面試題:'a' + + 'b' // 輸出什么

因為 + 'b' 等于 NaN竖配,所以結(jié)果為 "aNaN",你可能也會在一些代碼中看到過 + '1' 的形式來快速獲取 number 類型里逆。
或者轉(zhuǎn)化為 “a” + (+“b”)
"a" + + "1" => "a1"

那么對于除了加法的運算符來說,只要其中以一方為數(shù)字进胯,那么另一方也會被轉(zhuǎn)化成數(shù)字。

4 * '3' // 12
4 * [] // 0
4 * [1, 2] // NaN

比較運算符

  • 如果是對象原押,就通過 toPrimitive 轉(zhuǎn)換對象
  • 如果是字符串胁镐,就通過 unicode 字符索引來比較
let a = {
  valueOf() {
    return 0
  },
  toString() {
    return '1'
  }
}
a > -1 // true'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市诸衔,隨后出現(xiàn)的幾起案子希停,更是在濱河造成了極大的恐慌,老刑警劉巖署隘,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宠能,死亡現(xiàn)場離奇詭異,居然都是意外死亡磁餐,警方通過查閱死者的電腦和手機违崇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門阿弃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人羞延,你說我怎么就攤上這事渣淳。” “怎么了伴箩?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵入愧,是天一觀的道長。 經(jīng)常有香客問我嗤谚,道長棺蛛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任巩步,我火速辦了婚禮旁赊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘椅野。我一直安慰自己终畅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布竟闪。 她就那樣靜靜地躺著离福,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炼蛤。 梳的紋絲不亂的頭發(fā)上术徊,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音鲸湃,去河邊找鬼赠涮。 笑死,一個胖子當(dāng)著我的面吹牛暗挑,可吹牛的內(nèi)容都是我干的笋除。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炸裆,長吁一口氣:“原來是場噩夢啊……” “哼垃它!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烹看,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤国拇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后惯殊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酱吝,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年土思,在試婚紗的時候發(fā)現(xiàn)自己被綠了务热。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忆嗜。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖崎岂,靈堂內(nèi)的尸體忽然破棺而出捆毫,到底是詐尸還是另有隱情,我是刑警寧澤冲甘,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布绩卤,位于F島的核電站,受9級特大地震影響江醇,放射性物質(zhì)發(fā)生泄漏濒憋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一嫁审、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赖晶,春花似錦律适、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胳嘲,卻和暖如春厂僧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背了牛。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工颜屠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹰祸。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓甫窟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蛙婴。 傳聞我的和親對象是個殘疾皇子粗井,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容