工作中遇到的50個JavaScript的基礎知識點,滿分找我拿獎品

Sunshine_Lin發表於2021-11-05

前言

大家好,我是林三心,基礎是進階的前提,今天給大家分享一下,我這一年來工作中遇到的50個「基礎知識點」,我這一年來就有記錄知識點的習慣哈哈。滿分的可以找我拿禮品哦!

50個基礎知識點

1、JavaScript有幾種資料型別?

  • number:數字型別
  • string:字串型別
  • boolean:布林值型別
  • undefined:未定義型別
  • null:空值型別
  • object:物件型別
  • symbol:symbol型別
  • bigint:大數字型別

2、JavaScript最大安全數字與最小安全數字?

console.log(Number.MAX_SAFE_INTEGER)
// 9007199254740991

console.log(Number.MIN_SAFE_INTEGER)
// -9007199254740991

3、深拷貝與淺拷貝的區別?

  • 深拷貝層層拷貝,淺拷貝只拷貝第一層,深層只是引用
  • 在深拷貝中,新物件中的更改不會影響原始物件,而在淺拷貝中,新物件中的更改,原始物件中也會跟著改。
  • 在深拷貝中,原始物件不與新物件共享相同的屬性,而在淺拷貝中,它們具有相同的屬性。

4、閉包是什麼?

閉包是一個能讀取其他函式內部變數的函式

  • 優點:使外部能訪問到區域性的東西
  • 缺點:使用不當容易造成記憶體洩漏的問題
    例子:

    function a () {
    let num = 0
    
    // 這是個閉包
    return function () {
       return ++num
    }
    }
    const b = a()
    console.log(b()) // 1
    console.log(b()) // 2

5、原型鏈是什麼呀?詳細點!

看看我這篇文章:掘金講「原型鏈」,講的最好最通俗易懂的

6、什麼是變數提升?函式提升?

變數提升

console.log(name) // undefined
var name = 'Sunshine_Lin'

if (false) {
  var age = 23
}
console.log(age) // undefined 不會報錯

函式提升

console.log(fun) // function fun() {}
function fun() {}

if (false) {
  function fun2(){}
}
console.log(fun2) // undefined 不會報錯

函式提升優先順序 > 變數提升優先順序

console.log(fun) // function fun() {}
var fun = 'Sunshie_Lin'
function fun() {}
console.log(fun) // 'Sunshie_Lin'

7、isNaN 與 Number.isNaN的區別?

  • isNaN:除了判斷NaN為true,還會把不能轉成數字的判斷為true,例如'xxx'
  • Number.isNaN:只有判斷NaN時為true,其餘情況都為false

8、解決遍歷物件時,把原型上的屬性遍歷出來了咋辦?

使用 hasOwnProperty 判斷

function Person(name) {
  this.name = name
}
Person.prototype.age = 23
const person = new Person('Sunshine_lin')
for (const key in person) { console.log(key) } // name age
// 使用 hasOwnProperty
for (const key in person) {
  person.hasOwnProperty(key) && console.log(key)
} // name

9、valueOf 與 toString

  • 1、 valueOf 偏向於運算, toString 偏向於顯示
  • 2、物件轉換時,優先呼叫 toString
  • 3、強轉字串優先呼叫 toString ,強轉數字優先呼叫 valueOf
  • 4、正常情況下,優先呼叫 toString
  • 5、運算操作符情況下優先呼叫 valueOf

呼叫valueOf

呼叫者返回值返回值型別
Array陣列本身Array
Boolean布林值Boolean
Date毫秒數Number
Function函式本身Function
Number數字值Number
Object物件本身Object
String字串String

呼叫toString

呼叫者返回值返回值型別
Array陣列轉字串,相當於Array.join()String
Boolean轉字串'true'、'false'String
Date字串日期,如'Fri Dec 23 2016 11:24:47 GMT+0800 (中國標準時間)'String
Number數字字串String
Object'[object Object]'String
String字串String

10、JavaScript變數在記憶體中具體儲存形式?

  • 基本資料型別:存在 棧記憶體
  • 引用資料型別:指標存 棧記憶體 ,指向 堆記憶體 中一塊地址,內容存在堆記憶體中
  • 也有說法說其實JavaScript所有資料都存 堆記憶體 中,我也比較贊同這種說法

11、講一講JavaScript的裝箱和拆箱?

裝箱:把基本資料型別轉化為對應的引用資料型別的操作

看以下程式碼,s1只是一個基本資料型別,他是怎麼能呼叫indexOf的呢?

const s1 = 'Sunshine_Lin'
const index = s1.indexOf('_')
console.log(index) // 8

原來是JavaScript內部進行了裝箱操作

  • 1、建立String型別的一個例項;
  • 2、在例項上呼叫指定的方法;
  • 3、銷燬這個例項;

    var temp = new String('Sunshine_Lin')
    const index = temp.indexOf('_')
    temp = null
    console.log(index) // 8

    拆箱:將引用資料型別轉化為對應的基本資料型別的操作

    通過 valueOf 或者 toString 方法實現拆箱操作

    var objNum = new Number(123);  
    var objStr =new String("123");   
    console.log( typeof objNum ); //object
    console.log( typeof objStr ); //object 
    console.log( typeof objNum.valueOf() ); //number
    console.log( typeof objStr.valueOf() ); //string
    
    console.log( typeof objNum.toString() ); // string 
    console.log( typeof objStr.toString() ); // string

12、null和undefined的異同點有哪些?

相同點

  • 都是空變數
  • 都是假值,轉布林值都是false
  • null == undefined 為 true
    不同點
  • typeof判斷null為object,判斷undefined為undefined
  • null轉數字為0,undefined轉數字為NaN
  • null是一個物件未初始化,undefined是初始化了,但未定義賦值
  • null === undefined 為 false

13、如何判斷資料型別?

  • typeof xxx:能判斷出number,string,undefined,boolean,object,function(null是object)
  • Object.prototype.toString.call(xxx):能判斷出大部分型別
  • Array.isArray(xxx):判斷是否為陣列

14、為什麼typeof null 是object?

不同的資料型別在底層都是通過二進位制表示的,二進位制前三位為 000 則會被判斷為 object 型別,而null底層的二進位制全都是0,那前三位肯定也是 000 ,所以被判斷為 object

15、== 與 === 的區別?

  • ==:在比較過程中會存在隱式轉換
  • ===:需要型別相同,值相同,才能為true

16、JavaScript的隱式轉換規則?

  • 1、轉成string型別: +(字串連線符)
  • 2、轉成number型別:++/--(自增自減運算子) + - * / %(算術運算子) > < >= <= == != === !=== (關係運算子)
  • 3、轉成boolean型別:!(邏輯非運算子)

17、雙等號左右兩邊的轉換規則?

  • 1、null == undefined 為 true
  • 1、如果有一個運算元是布林值,則在比較相等性之前先將其轉換為數值——false轉換為0,而true轉換為1;
  • 2、如果一個運算元是字串,另一個運算元是數值,在比較相等性之前先將字串轉換為數值
  • 3、如果一個運算元是物件,另一個運算元不是,則呼叫物件的toString()方法,用得到的基本型別值按照前面的規則進行比較

18、undefined >= undefined 為什麼是 false ?

按照隱式轉換規則,可轉換成 NaN >= NaN ,NaN 不等於 NaN,也不大於,所以是 false

19、null >= null 為什麼是 true?

按照隱式轉換規則,可轉換成 0 >= 0 ,0 等於 0,所以是 true

20、[] == ![] 為什麼是 true ?

按照雙等號左右兩邊的轉換規則

  • 1、 ! 優先順序高於 == [] 不是假值,所以先轉換成 [] == false
  • 2、右邊為布林值, false 先轉數字 0 ,所以可轉換為 [] == 0
  • 3、左邊為物件, [] 呼叫 toString 轉為 '' ,轉換為 '' == 0
  • 4、左邊為字串, '' 轉換為 0 ,最終為 0 == 0

21、0.1 + 0.2 === 0.3,對嗎?

不對,JavaScript的計算存在精度丟失問題

console.log(0.1 + 0.2 === 0.3) // false
  • 原因:JavaScript中小數是浮點數,需轉二進位制進行運算,有些小數無法用二進位制表示,所以只能取近似值,所以造成誤差
  • 解決方法:

    • 先變成整數運算,然後再變回小數
    • toFixed() 效能不好,不推薦

22、什麼是匿名函式?

匿名函式:就是沒有函式名的函式,如:

(function(x, y){
    alert(x + y);  
})(2, 3);

這裡建立了一個匿名函式(在第一個括號內),第二個括號用於呼叫該匿名函式,並傳入引數。

23、繫結點選事件有幾種方式?

三種

  • xxx.onclick = function (){}
  • <xxx onclick=""></xxx>
  • xxx.addEventListence('click', function(){}, false)

24、addEventListence的第三個引數是幹嘛的?

第三個變數傳一個布林值,需不需要阻止冒泡,預設是false,不阻止冒泡

25、函式宣告和函式表示式的區別?

  • 函式宣告:享受函式提升
  • 函式表示式:歸類於變數宣告,享受變數提升
  • 函式提升優先順序 > 變數提升優先順序

    console.log(fun) // fun () {}
    // 函式表示式
    var fun = function(name) {}
    // 函式宣告
    function fun () {}
    console.log(fun) // fun (name) {}

26、JavaScript的事件流模型有哪些?

  • 事件冒泡:由最具體的元素接收,並往上傳播
  • 事件捕獲:由最不具體的元素接收,並往下傳播
  • DOM事件流:事件捕獲 -> 目標階段 -> 事件冒泡

27、Ajax、Axios、Fetch有啥區別?

  • Ajax:是對XMLHttpRequest物件(XHR)的封裝
  • Axios:是基於Promise對XHR物件的封裝
  • Fetch:是window的一個方法,也是基於Promise,但是與XHR無關,不支援IE

28、load、$(document).ready、DOMContentLoaded的區別?

DOM文件載入的步驟為:

  • 1、解析HTML結構。
  • 2、載入外部指令碼和樣式表檔案。
  • 3、解析並執行指令碼程式碼。
  • 4、DOM樹構建完成。// DOMContentLoaded 觸發、 $(document).ready 觸發
  • 5、載入圖片等外部檔案。
  • 6、頁面載入完畢。// load 觸發

29、如何阻止事件冒泡?

function stopBubble(e) {
  if (e.stopPropagation) {
    e.stopPropagation()
  } else {
    window.event.cancelBubble = true;
  }
}

30、如何阻止事件預設行為?

function stopDefault(e) {
  if (e.preventDefault) {
    e.preventDefault();
  } else {
    window.event.returnValue = false;
  }
}

31、什麼是事件委託?

當所有子元素都需要繫結相同的事件的時候,可以把事件繫結在父元素上,這就是 事件委託 ,優點有:

  • 繫結在父元素上只需要繫結一次,節省效能
  • 子元素不需要每個都去繫結同一事件
  • 如果後續又有新的子元素新增,會由於事件委託的原因,自動接收到父元素的事件監聽

32、如何實現陣列去重?

// 使用 Map 去重
function quchong1(arr) {
  const newArr = []
  arr.reduce((pre, next) => {
    if (!pre.get(next)) {
      pre.set(next, 1)
      newArr.push(next)
    }
    return pre
  }, new Map())
  return newArr
}

// 使用 Set 去重
function quchong (arr) {
    return [...new Set(arr)]
}

33、Set與Array的區別是什麼?

建議看阮一峰老師的文章:Set 和 Map 資料結構

34、Map與Object的區別是什麼?

建議看阮一峰老師的文章:Set 和 Map 資料結構

35、NaN是什麼?有什麼特點?

  • NaN不等於自身,也就是 NaN === NaNfalse
  • NaN為假值,轉布林值為false
  • NaN本質是一個number, typeof NaN === number

36、處理非同步的方法有哪些?

  • 回撥函式
  • promise
  • 事件監聽
  • 釋出訂閱
  • async await

    37、JavaScript繼承方式有幾種?

    前置工作

    // 定義一個動物類
    function Animal (name) {
    // 屬性
    this.name = name || 'Animal';
    // 例項方法
    this.sleep = function(){
      console.log(this.name + '正在睡覺!');
    }
    }
    // 原型方法
    Animal.prototype.eat = function(food) {
    console.log(this.name + '正在吃:' + food);
    };

    1、原型鏈繼承

    核心:將父類的例項作為子類的原型

    function Cat(){ 
    }
    Cat.prototype = new Animal();
    Cat.prototype.name = 'cat';
    
    var cat = new Cat();
    console.log(cat.name); // cat
    cat.eat('fish') // cat正在吃:fish
    cat.sleep() // cat正在睡覺!
    console.log(cat instanceof Animal); //true 
    console.log(cat instanceof Cat); //true

    優點:

  • 1、非常純粹的繼承關係,例項是子類的例項,也是父類的例項
  • 2、父類新增原型方法/屬性,子類都能訪問到
  • 3、簡單,易於實現
    缺點:
  • 1、要想為子類新增屬性和方法,必須要在 new Animal() 這樣的語句之後執行,不能放構造器中
  • 2、來自原型物件的所有屬性被所有例項共享
  • 3、建立子例項時,無法向父類建構函式傳參
  • 4、不支援多繼承

2、構造繼承

核心:使用父類的構造器來增強子類例項,等於是複製父類的例項屬性給子類(沒用到原型)

function Cat(name) {
  Animal.call(this);
  this.name = name || 'Tom';
}

var cat = new Cat();
console.log(cat.name); // Tom
cat.sleep() // Tom正在睡覺!
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

優點:

  • 1、解決了 原型鏈繼承 中,子類例項共享父類引用屬性的問題
  • 2、建立子類例項時,可以向父類傳遞引數
  • 3、可以實現多繼承(call多個父類物件)
    缺點:
  • 1、例項並不是父類的例項,知識子類的例項
  • 2、是能繼承父類的例項屬性和方法,不能繼承原型屬性/方法
  • 3、無法實現函式複用,每個子類都有父類例項函式的副本,影響效能

3、例項繼承

核心:為父類例項新增新特性,作為子類例項返回

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

var cat = new Cat();
console.log(cat.name) // Tom
cat.sleep() // Tom正在睡覺!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

優點:

  • 1、不限制呼叫方式,不管是 new 子類() 還是 子類() ,返回的物件具有相同效果
    缺點:
  • 1、例項是父類的例項,不是子類的例項
  • 2、不支援多繼承

4、拷貝繼承

核心:就一個一個拷貝

function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  this.name = name || 'Tom';
}

var cat = new Cat();
console.log(cat.name); // Tom
cat.sleep() // Tom正在睡覺!
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

優點:

  • 1、支援多繼承
    缺點:
  • 1、效率低,記憶體佔用高(因為要拷貝父類的屬性)
  • 2、無法獲取父類不可列舉方法(不可列舉方法,不能使用for in訪問到)

5、組合繼承

核心:通過父類構造,繼承父類的屬性並保留傳參的有點,然後通過將父類例項作為子類原型,實現函式複用

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();

Cat.prototype.constructor = Cat;

var cat = new Cat();
console.log(cat.name); // Tom
cat.sleep() // Tom正在睡覺!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

優點:

  • 1、彌補了 構造繼承 的缺陷,可以繼承例項屬性/方法,也可繼承原型屬性/方法
  • 2、既是子類的例項,也是父類的例項
  • 3、不存在引用屬性共享問題
  • 4、可傳參
  • 5、函式可複用
    缺點:
  • 1、呼叫了兩次父類建構函式,生成了兩份例項(子類例項將子類原型上的那份遮蔽了)

6、寄生組合繼承

核心:通過寄生方式,砍掉父類的例項屬性,這樣,在呼叫兩次父類的構造時,就不會初始化兩次例項方法/屬性,避免 繼承組合 的缺點

function Cat(name) {
  Animal.call(this);
  this.name = name || 'Tom';
}
// 建立一個沒有例項方法的類
var Super = function () { };
Super.prototype = Animal.prototype;
//將例項作為子類的原型
Cat.prototype = new Super();

// Test Code
var cat = new Cat();
console.log(cat.name); // Tom
cat.sleep() // Tom正在睡覺!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true

優點:

  • 1、堪稱完美
    缺點:
  • 1、實現複雜

38、建立一個物件的方式有哪幾種?

new Object建立

const obj = new Object()
obj.name = 'Sunshine_Lin'

字面量建立

const obj = { name: 'Sunshin_Lin' }

工廠模式建立

function createObj(name) {
  const obj = new Object()
  obj.name = name
  return obj
}
const obj = createObj('Sunshine_Lin')

建構函式建立

function Person(name) {
  this.name = name
}
const person = new Person('Sunshine_Lin')

39、this指向的四種情況?

  • 1、new操作符建立例項

    function Person(name) {
    this.name = name
    console.log(this)
    }
    // this指向當前person例項物件
    const person = new Person('Sunshine_Lin')
  • 2、指向window

    function fn() {
    console.log(this)
    }
    fn() // 瀏覽器window,node裡global
  • 3、物件呼叫方法

    const target = {
    fn: function () { console.log(this) }
    }
    target.fn() // target
    
    // 這種就是改變了this了
    const fn = target.fn
    fn() // 瀏覽器window,node裡global
  • 4、call、apply、bind改變this

    const obj1 = {
    name: '林三心',
    sayName: function() {
      console.log(this.name)
    }
    }
    const obj2 = {
    name: 'Sunshin_Lin'
    }
    // 改變sayName的this指向obj2
    obj1.sayName.call(obj2) // Sunshin_Lin
    // 改變sayName的this指向obj2
    obj1.sayName.apply(obj2) // Sunshin_Lin
    // 改變sayName的this指向obj2
    const fn = obj1.sayName.bind(obj2)
    fn() // Sunshin_Lin

40、陣列的常用方法有哪些?

方法作用是否影響原陣列
push在陣列後新增元素,返回陣列長度
pop刪除陣列最後一項,返回被刪除項
shift刪除陣列第一項,並返回陣列
unshift陣列開頭新增元素,返回新增的元素
reserve反轉一個陣列,返回修改後的陣列
sort排序一個陣列,返回修改後的陣列
splice擷取陣列,返回被擷取的區間
join將一個陣列所有元素連線成字串並返回這個字串
concatarr1.concat(arr2, arr3) 連線陣列
joinarr.join(x)將arr陣列元素連線成字串並返回這個字串
map運算元組每一項並返回一個新陣列
forEach遍歷陣列,沒有返回值
filter對陣列所有項進行判斷,返回符合規則的新陣列
every陣列每一項都符合規則才返回true
some陣列有符合規則的一項就返回true
reduce接收上一個return和陣列的下一項
flat陣列扁平化
slice擷取陣列,返回被擷取的區間

41、Math的常用方法有哪些?

方法作用
Math.max(arr)取arr中的最大值
Math.min(arr)取arr中的最小值
Math.ceil(小數)小數向上取整
Math.floor(小數)小數向下取整
Math.round(小數)小數四捨五入
Math.sqrt(num)對num進行開方
Math.pow(num, m)對num取m次冪
Math.random() * num取0-num的隨機數

42、哪些因素導致記憶體洩漏?如何解決?

請看我這篇文章哪是大神?只是用他人七夕約會時間,整理「JS避免記憶體洩漏」罷了

43、講講JavaScript的垃圾回收機制

看我這篇文章:贈你13張圖,助你20分鐘打敗了「V8垃圾回收機制」

44、JS中有哪些不同型別的彈出框?

在JS中有三種型別的彈出框可用,分別是:

  • Alert
  • Confirm
  • Prompt

    45. 如何將 JS 日期轉換為ISO標準

toISOString() 方法用於將js日期轉換為ISO標準。 它使用ISO標準將js Date物件轉換為字串。如:

var date = new Date();
var n = date.toISOString();
console.log(n);
// YYYY-MM-DDTHH:mm:ss.sssZ

46、如何在JS中編碼和解碼 URL

encodeURI() 函式用於在JS中對URL進行編碼。它將url字串作為引數並返回編碼的字串。

注意: encodeURI()不會編碼類似這樣字元: / ? : @ & = + $ #,如果需要編碼這些字元,請使用encodeURIComponent()。 用法:

var uri = "my profile.php?name=sammer&occupation=pāntiNG";
var encoded_uri = encodeURI(uri);

decodeURI() 函式用於解碼js中的URL。它將編碼的url字串作為引數並返回已解碼的字串,用法:

var uri = "my profile.php?name=sammer&occupation=pāntiNG";
var encoded_uri = encodeURI(uri);
decodeURI(encoded_uri);

47、什麼是BOM?有哪些api?

BOM就是 browser object model 瀏覽器物件模型

api作用代表方法或屬性
window.history操縱瀏覽器的記錄history.back()
history.go(-1)
window.innerHeight獲取瀏覽器視窗的高度
window.innerWidth獲取瀏覽器視窗的寬度
window.location操作重新整理按鈕和位址列location.host:獲取域名和埠
location.hostname:獲取主機名
location.port:獲取埠號
location.pathname:獲取url的路徑
location.search:獲取?開始的部分
location.href:獲取整個url
location.hash:獲取#開始的部分
location.origin:獲取當前域名
location.navigator:獲取當前瀏覽器資訊

48、BOM 和 DOM 的關係

BOM全稱Browser Object Model,即瀏覽器物件模型,主要處理瀏覽器視窗和框架。

DOM全稱Document Object Model,即文件物件模型,是 HTML 和XML 的應用程式介面(API),遵循W3C 的標準,所有瀏覽器公共遵守的標準。

JS是通過訪問BOM(Browser Object Model)物件來訪問、控制、修改客戶端(瀏覽器),由於BOM的window包含了document,window物件的屬性和方法是直接可以使用而且被感知的,因此可以直接使用window物件的document屬性,通過document屬性就可以訪問、檢索、修改XHTML文件內容與結構。因為document物件又是DOM的根節點。

可以說,BOM包含了DOM(物件),瀏覽器提供出來給予訪問的是BOM物件,從BOM物件再訪問到DOM物件,從而js可以操作瀏覽器以及瀏覽器讀取到的文件。

49、JS中的substr()和substring()函式有什麼區別

substr() 函式的形式為substr(startIndex,length)。 它從startIndex返回子字串並返回'length'個字元數。

var s = "hello";
( s.substr(1,4) == "ello" ) // true

substring() 函式的形式為substring(startIndex,endIndex)。 它返回從startIndex到endIndex - 1的子字串。

var s = "hello";
( s.substring(1,4) == "ell" ) // true

50、解釋一下 "use strict" ?

“use strict”是Es5中引入的js指令。 使用“use strict”指令的目的是強制執行嚴格模式下的程式碼。 在嚴格模式下,我們們不能在不宣告變數的情況下使用變數。 早期版本的js忽略了“use strict”。

結語

如果你覺得此文對你有一丁點幫助,點個贊,鼓勵一下林三心哈哈。或者可以加入我的摸魚群
想進學習群,摸魚群,請檢視我首頁加我,並備註:思否,我會定時直播模擬面試,答疑解惑

滿分的趕緊找我!!!或者評論區告訴我哦~~~

image.png

相關文章