2022年前端js面試題

還有部分沒更新完...

var、let、const區(qū)別

1. var存在變量提升,而let、const沒有
2. let、const有塊級作用域,而var沒有
3. var 在同一塊作用域可以重復(fù)聲明多個相同的變量,后者覆蓋前者,let、const重
復(fù)聲明會報錯
4.let、var聲明變量后可以進(jìn)行改變值,const聲明不能修改([對象、數(shù)組]的屬性和方法可以改變

合并對象的方法可以寫幾種

const obj1 = {a:'a',b:'b',c:'c'};
const obj2 = {c:'c',d:'d',e:'e'};
方式一:使用ES6的拓展運(yùn)算符
{...obj1,...obj2}
方式二:Object.assign(obj1,obj2);
方式三:手寫遍歷
function assign(obj1,obj2){
    for(let key in obj2){
        obj1[key] = obj2[key];
    }
   return obj1;
}
assign(obj1,obj2);

find和filter的區(qū)別

1. find 條件符合就找到第一個符合的元素返回,否則返回 undefined
2. filter 如果條件符合  就返回一個新的數(shù)組(多個元素),否則返回空數(shù)組[]

some和every的區(qū)別

1. every()是對數(shù)組中每一項運(yùn)行給定函數(shù),如果該函數(shù)對每一項返回true,則返回true。 有點(diǎn)&&的意思
2. some()是對數(shù)組中每一項運(yùn)行給定函數(shù),如果該函數(shù)對任一項返回true,則返回true。有點(diǎn)||的意思

深拷貝和淺拷貝

箭頭函數(shù)和普通函數(shù)有什么區(qū)別

1. 箭頭函數(shù)不能用于構(gòu)造函數(shù),如果使用會報錯
2. 箭頭函數(shù)沒有 arguments對象、prototype 原型對象
3. 箭頭函數(shù)的this在定義時就已經(jīng)指定,而普通函數(shù)是調(diào)用時才指定,如果普通函數(shù)用于構(gòu)造函數(shù)this的指向就是當(dāng)前實例

Promise有幾種狀態(tài)

1. pending(初始狀態(tài))
   pending的意思是“待定的,發(fā)生的”,相當(dāng)于是一個初始狀態(tài)。創(chuàng)建[Promise]對象時,且沒有調(diào)用resolve或者是reject方法,相當(dāng)于時初始狀態(tài)。這個初始狀態(tài)會隨著你調(diào)用resolve,或者是reject函數(shù)而切換到另一種狀態(tài)。

2 . resolved(成功態(tài))
    resolved表示成功了。當(dāng)[Promise]實例對象中異步任務(wù)順利完成且返回結(jié)果值時,就調(diào)用了resolved這個參數(shù)

3. rejected(失敗狀態(tài))
   rejected 失敗,當(dāng)[Promise]實例對象中異步任務(wù)執(zhí)行失敗時,就調(diào)用了resolved這個參數(shù)

localstorage、sessionstorage、cookie的區(qū)別

一、存儲的時間有效期不同
1、cookie的有效期是可以設(shè)置的,默認(rèn)的情況下是關(guān)閉瀏覽器后失效
2、sessionStorage的有效期是僅保持在當(dāng)前頁面,關(guān)閉當(dāng)前會話頁或者瀏覽器后就會失效
3、localStorage的有效期是在不進(jìn)行手動刪除的情況下是一直有效的

二、存儲的大小不同
1、cookie的存儲是4kb左右,存儲量較小,一般頁面最多存儲20條左右信息
2、localStorage和sessionStorage的存儲容量是5Mb(官方介紹,可能和瀏覽器有部分差異性)

三、與服務(wù)端的通信
1、cookie會參與到與服務(wù)端的通信中,一般會攜帶在http請求的頭部中,例如一些關(guān)鍵密匙驗證等。
2、localStorage和sessionStorage是單純的前端存儲,不參與與服務(wù)端的通信

JS數(shù)據(jù)類型有哪些

基本類型:String、Number、Boolean、Undefined、Null、Symbol、Bigint
引用類型:Object(Array、Function、Date、RegExp)
注意:typeof null 返回的是 'object' 
      NaN是一個Number類型,但是不是一個具體的數(shù)字
      typeof NaN 返回的是 'number'

null和undefined的區(qū)別

1. 作者在設(shè)計js的都是先設(shè)計的null(為什么設(shè)計了null:最初設(shè)計js的時候借鑒了java的語言)
2. null會被隱式轉(zhuǎn)換成0,很不容易發(fā)現(xiàn)錯誤。
3. 先有null后有undefined,出來undefined是為了填補(bǔ)之前的坑。
具體區(qū)別:JavaScript的最初版本是這樣區(qū)分的:null是一個表示"無"的對象(空對象指針),轉(zhuǎn)為數(shù)值時為0;undefined是一個表示"無"的原始值,轉(zhuǎn)為數(shù)值時為NaN。

==和===有什么不同

==  :  比較的是值
        
        string == number || boolean || number ....都會隱式轉(zhuǎn)換
        通過valueOf轉(zhuǎn)換(valueOf() 方法通常由 JavaScript 在后臺自動調(diào)用,并不顯式地出現(xiàn)在代碼中。)

=== : 除了比較值,還比較類型

JS微任務(wù)和宏任務(wù)

1. js是單線程的語言。
2. js代碼執(zhí)行流程:同步執(zhí)行完==>事件循環(huán)
    同步的任務(wù)都執(zhí)行完了,才會執(zhí)行事件循環(huán)的內(nèi)容
    進(jìn)入事件循環(huán):請求、定時器、事件....
3. 事件循環(huán)中包含:【微任務(wù)、宏任務(wù)】
微任務(wù):promise.then
宏任務(wù):setTimeout..

要執(zhí)行宏任務(wù)的前提是清空了所有的微任務(wù)

流程:同步 > 事件循環(huán)【微任務(wù)和宏任務(wù)】> 微任務(wù) > 宏任務(wù) > 微任務(wù)...

JS作用域

1. 除了函數(shù)外,js是沒有塊級作用域。
2. 作用域鏈:內(nèi)部可以訪問外部的變量,但是外部不能訪問內(nèi)部的變量。
     注意:如果內(nèi)部有,優(yōu)先查找到內(nèi)部,如果內(nèi)部沒有就查找外部的。
3. 注意聲明變量是用var還是沒有寫(window.)
4. 注意:js有變量提升的機(jī)制【變量懸掛聲明】
5. 優(yōu)先級:聲明變量 > 聲明普通函數(shù) > 參數(shù) > 變量提升

JS判斷變量是不是數(shù)組,你能寫出哪些方法

1. isArray
2. Array.prototype.isPrototypeOf([])
3. Object.prototype.toString.call([]).indexOf('Array') > -1
4. [].constructor.toString().indexOf('Array') > -1

slice是干嘛的、splice是否會改變原數(shù)組

1. slice是來截取的
    參數(shù)可以寫slice(3)、slice(1,3)、slice(-3)
    返回的是一個新的數(shù)組
2. splice 功能有:插入、刪除、替換
    返回:刪除的元素
    該方法會改變原數(shù)組

JS數(shù)組去重

方式一:new set

const arr= [1,2,3,2,4,1];
function unique(arr){
    return [...new Set(arr)]
}

方式二:Object的key是唯一
function unique(arr) {
  const param = {};
  arr.forEach(key => {
    param[key] = key;
  });
  return Object.keys(param);
};

方式三:indexOf

function unique( arr ){
    var brr = [];
    for( var i=0;i<arr.length;i++){
        if(  brr.indexOf(arr[i]) == -1 ){
            brr.push( arr[i] );
        }
    }
    return brr;
}

方式四:sort

function unique( arr ){
    arr = arr.sort();
    var brr = [];
    for(var i=0;i<arr.length;i++){
        if( arr[i] !== arr[i-1]){
            brr.push( arr[i] );
        }
    }
    return brr;
}

找出多維數(shù)組最大值

function fnArr(arr){
    var newArr = [];
    arr.forEach((item,index)=>{
        newArr.push( Math.max(...item)  )
    })
    return newArr;
}
console.log(fnArr([
    [4,5,1,3],
    [13,27,18,26],
    [32,35,37,39],
    [1000,1001,857,1]
]));

給字符串新增方法實現(xiàn)功能

給字符串對象定義一個addPrefix函數(shù),當(dāng)傳入一個字符串str時,它會返回新的帶有指定前綴的字符串,例如: console.log( 'world'.addPrefix('hello') ) 控制臺會輸出helloworld

String.prototype.addPrefix = function(str){
    return str  + this;
}
console.log( 'world'.addPrefix('hello') )

找出字符串出現(xiàn)最多次數(shù)的字符以及次數(shù)

var str = 'aaabbbbbccddddddddddx';
var obj = {};
for(var i=0;i<str.length;i++){
    var char = str.charAt(i);
    if( obj[char] ){
        obj[char]++;
    }else{
        obj[char] = 1;
    }
}
console.log( obj );
//統(tǒng)計出來最大值
var max = 0;
for( var key in obj ){
    if( max < obj[key] ){
        max = obj[key];
    }
}
//拿最大值去對比
for( var key in obj ){
    if( obj[key] == max ){
        console.log('最多的字符是'+key);
        console.log('出現(xiàn)的次數(shù)是'+max);
    }
}

new操作符具體做了什么

1. 創(chuàng)建了一個空的對象
2. 將空對象的原型,指向于構(gòu)造函數(shù)的原型
3. 將空對象作為構(gòu)造函數(shù)的上下文(改變this指向)
4. 對構(gòu)造函數(shù)有返回值的處理判斷

實現(xiàn)代碼如下 :
function Fun( age,name ){
    this.age = age;
    this.name = name;
}
function create( fn , ...args ){
    var obj = {};
    Object.setPrototypeOf(obj,fn.prototype);
    var result = fn.apply(obj,args);
    return result instanceof Object ? result : obj;
}
console.log( create(Fun,18,'張三')   )

說一下call、apply、bind區(qū)別

1. 共同點(diǎn):功能一致,都是可以改變this指向
2. 語法: 函數(shù).call()、函數(shù).apply()、函數(shù).bind()
3. 區(qū)別一:參數(shù)不同,apply第二個參數(shù)是數(shù)組,call和bind有多個參數(shù)需要挨個寫
   區(qū)別二:call、apply都是立即執(zhí)行 bind不會立即執(zhí)行,因為bind返回的是一個函數(shù)需要加入()執(zhí)行

場景:

1. 用apply的情況
var arr1 = [1,2,4,5,7,3,321];
console.log( Math.max.apply(null,arr1) )

2. 用bind的情況
var btn = document.getElementById('btn');
var h1s = document.getElementById('h1s');
btn.onclick = function(){
    console.log( this.id );
}.bind(h1s)

閉包

1. 閉包是什么
    閉包是一個函數(shù)加上到創(chuàng)建函數(shù)的作用域的連接,閉包“關(guān)閉”了函數(shù)的自由變量。
2. 閉包可以解決什么問題【閉包的優(yōu)點(diǎn)】
    2.1 內(nèi)部函數(shù)可以訪問到外部函數(shù)的局部變量
    2.2 閉包可以解決的問題
            var lis = document.getElementsByTagName('li');
      for(var i=0;i<lis.length;i++){
        (function(i){
          lis[i].onclick = function(){
            alert(i);
          }
        })(i)
      }
3. 閉包的缺點(diǎn)
    3.1 變量會駐留在內(nèi)存中,造成內(nèi)存損耗問題。
                解決:把閉包的函數(shù)設(shè)置為null
  3.2 內(nèi)存泄漏【ie】 ==> 可說可不說,如果說一定要提到ie

原型鏈


1. 原型可以解決什么問題:解決了對象的共享屬性、方法
2. 誰有原型:函數(shù)擁有prototype、對象擁有__proto__
3. 對象查找屬性或者方法的順序
    先在對象本身查找 > 構(gòu)造函數(shù)中查找 > 對象的原型 > 構(gòu)造函數(shù)的原型中 > 當(dāng)前原型的原型中查找
4. 原型鏈的最頂端是null

JS繼承有哪些方式

1. ES6 class 的extends
2. 原型鏈繼承
3. 借用構(gòu)造函數(shù)繼承
4. 組合式繼承(原型鏈繼承和借用構(gòu)造函數(shù)繼承)

方式一:ES6
class Parent{
    constructor(){
        this.age = 18;
    }
}

class Child extends Parent{
    constructor(){
        super();
        this.name = '張三';
    }
}
let o1 = new Child();
console.log( o1,o1.name,o1.age );


方式二:原型鏈繼承

function Parent(){
    this.age = 20;
}
function Child(){
    this.name = '張三'
}
Child.prototype = new Parent();
let o2 = new Child();
console.log( o2,o2.name,o2.age );


方式三:借用構(gòu)造函數(shù)繼承

function Parent(){
    this.age = 22;
}
function Child(){
    this.name = '張三'
    Parent.call(this);
}
let o3 = new Child();
console.log( o3,o3.name,o3.age );

方式四:組合式繼承

function Parent(){
    this.age = 100;
}
function Child(){
    Parent.call(this);
    this.name = '張三'
}
Child.prototype = new Parent();
let o4 = new Child();
console.log( o4,o4.name,o4.age );

延遲加載JS有哪些方式

1. defer 是等html全部解析完成,才會執(zhí)行js代碼,順次執(zhí)行js腳本。
2. async 是和html解析同步的(并行的),不是順次執(zhí)行js腳本(誰先加載完誰先執(zhí)行)
3. 使用js動態(tài)創(chuàng)建<script type="text/javascript" src="xxx">標(biāo)簽
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容