日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js高频面试题

發布時間:2023/12/29 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js高频面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、延遲加載JS有哪些方式?

延遲加載:async、defer

  • 例如:<script defer type="text/javascript" src='script.js'></script>

defer : 等html全部解析完成,才會執行js代碼,順次執行js腳本。
async : async是和html解析同步的(一起的),不是順次執行js腳本(誰先加載完誰先執行)。

?二、JS數據類型有哪些?

基本類型:string、number、boolean、undefined、null、symbol、bigint
引用類型:object

NaN是一個數值類型,但是不是一個具體的數字。

三、JS數據類型考題

考題一:

console.log( true + 1 ); ? ? ?? ??? ??? ?//2 console.log( 'name'+true ); ??? ??? ??? ?//nametrue console.log( undefined + 1 ); ?? ??? ? ? ?//NaN console.log( typeof undefined ); ? ? ? ?//undefined

考題二:

console.log( typeof(NaN) ); ? ? ? //number console.log( typeof(null) );? ? ? //object

?四、null和undefined的區別

1. 作者在設計js的都是先設計的null(為什么設計了null:最初設計js的時候借鑒了java的語言)
2. null會被隱式轉換成0,很不容易發現錯誤。
3. 先有null后有undefined,出來undefined是為了填補之前的坑。

具體區別:JavaScript的最初版本是這樣區分的:null是一個表示"無"的對象(空對象指針),轉為數值時為0;undefined是一個表示"無"的原始值,轉為數值時為NaN。

五、==和===有什么不同? ?

== ?: ?比較的是值

????????string == number || boolean || number ....都會隱式轉換
?? ??? ?通過valueOf轉換(valueOf() 方法通常由 JavaScript 在后臺自動調用,并不顯式地出現在代碼中。)

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

六、JS微任務和宏任務

1. js是單線程的語言。
2. js代碼執行流程:同步執行完==》事件循環
?? ?同步的任務都執行完了,才會執行事件循環的內容
?? ?進入事件循環:請求、定時器、事件....
3. 事件循環中包含:【微任務、宏任務】
微任務:promise.then
宏任務:setTimeout..

要執行宏任務的前提是清空了所有的微任務

流程:同步==》事件循環【微任務和宏任務】==》微任務==》宏任務=》微任務...

七、JS作用域考題

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

?考題一:

function c(){var b = 1;function a(){console.log( b );var b = 2;console.log( b );}a();console.log( b ); } c();

考題二:

var name = 'a'; (function(){if( typeof name == 'undefined' ){var name = 'b';console.log('111'+name);}else{console.log('222'+name);} })()

考題三:

function fun( a ){var a = 10;function a(){}console.log( a ); }fun( 100 );

八、JS對象考題

JS對象注意點:

1. 對象是通過new操作符構建出來的,所以對象之間不想等(除了引用外);
2. 對象注意:引用類型(共同一個地址);
3. 對象的key都是字符串類型;
4. 對象如何找屬性|方法;
?? ?查找規則:先在對象本身找 ===> 構造函數中找 ===> 對象原型中找 ===> 構造函數原型中找 ===> 對象上一層原型查找

考題一:

[1,2,3] === [1,2,3] //false

?考題二:

var obj1 = {a:'hellow' } var obj2 = obj1; obj2.a = 'world'; console.log(obj1); //{a:world} (function(){console.log(a); //undefinedvar a = 1; })();

考題三:

var a = {} var b = {key:'a' } var c = {key:'c' }a[b] = '123'; a[c] = '456';console.log( a[b] ); // 456

九、JS作用域+this指向+原型的考題

考題一:

function Foo(){getName = function(){console.log(1)} //注意是全局的window.return this; }Foo.getName = function(){console.log(2)} Foo.prototype.getName = function(){console.log(3)} var getName = function(){console.log(4)} function getName(){console.log(5) }Foo.getName(); //2 getName(); //4 Foo().getName(); //1 getName(); //1 new Foo().getName();//3

考題二:

var o = {a:10,b:{a:2,fn:function(){console.log( this.a ); // 2console.log( this ); //代表b對象}} } o.b.fn();

考題三:

window.name = 'ByteDance'; function A(){this.name = 123; } A.prototype.getA = function(){console.log( this );return this.name + 1; } let a = new A(); let funcA = a.getA; funcA(); //this代表window

考題四:

var length = 10; function fn(){return this.length + 1; } var obj = {length:5,test1:function(){return fn();} } obj.test2 = fn; console.log( obj.test1() ); //1 console.log( fn()===obj.test2() ); //false console.log( obj.test1() == obj.test2() ); //false

十、JS判斷變量是不是數組,你能寫出哪些方法?

方式一:isArray

var arr = [1,2,3]; console.log( Array.isArray( arr ) );

方式二:instanceof 【可寫,可不寫】

var arr = [1,2,3]; console.log( arr instanceof Array );

方式三:原型prototype

var arr = [1,2,3]; console.log( Object.prototype.toString.call(arr).indexOf('Array') > -1 );

方式四:isPrototypeOf()

var arr = [1,2,3]; console.log( Array.prototype.isPrototypeOf(arr) )

方式五:constructor

var arr = [1,2,3]; console.log( arr.constructor.toString().indexOf('Array') > -1 )

十一、slice是干嘛的、splice是否會改變原數組

1. slice是來截取的

  • 參數可以寫slice(3)、slice(1,3)、slice(-3)
  • 返回的是一個新的數組

2. splice 功能有:插入、刪除、替換

  • 返回:刪除的元素
  • 該方法會改變原數組

?十二、JS數組去重

方式一:new set

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

方式二:indexOf

var arr2 = [1,2,3,2,4,1]; 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; } console.log( unique(arr2) );

方式三:sort

var arr3 = [1,2,3,2,4,1]; 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; } console.log( unique(arr3) );

?十三、找出多維數組最大值

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] ]));

?十四、給字符串新增方法實現功能

給字符串對象定義一個addPrefix函數,當傳入一個字符串str時,它會返回新的帶有指定前綴的字符串,例如:

console.log( 'world'.addPrefix('hello') ) 控制臺會輸出helloworld

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

?十五、找出字符串出現最多次數的字符以及次數

var str = 'aaasdwqeasdaqwd';var o = {};for (var i = 0; i < str.length; i++) {var index = str[i];if (!o[index]) {o[index] = 1;} else {o[index]++;}}var max = 0;var str1 = '';for (var k in o) {if (o[k] > max) {max = o[k];str1 = k;}}console.log('出現最多的次數:' + max + '及其字母為:' + str1);

?十六、new操作符具體做了什么

  • 在內存中創建一個新的空對象。
  • 讓 this 指向這個新的對象。
  • 執行構造函數里面的代碼,給這個新對象添加屬性和方法
  • 返回這個新對象(所以構造函數里面不需要return)
  • ?十七、閉包

    1. 閉包是什么
    ?? ?閉包是一個函數加上到創建函數的作用域的連接,閉包“關閉”了函數的自由變量。

    ?優點:

    • 可以訪問到函數內部的局部變量,
    • 可以避免全局變量的污染,
    • 這些變量的值始終保持在內存中,不會在外層函數調用后被自動清除(不會被垃圾回收)。

    缺點:會增大內存使用量,濫用閉包會影響性能,導致內存泄漏【如果說一定要提到ie】等問題。

    解決方法:在退出函數之前,將不使用的局部變量全部刪除,可以使變量賦值為null。

    2. 什么是垃圾?

    • 沒有被引用的對象或變量
    • 無法訪問到的對象

    垃圾回收機制:

    執行環境負責管理代碼執行過程中使用的內存。JS的垃圾回收機制是為了以防內存泄漏,內存泄漏的含義就是當已經不需要某塊內存時這塊內存還存在著,沒有被釋放,導致該內存無法被使用,垃圾回收機制就是間歇的不定期的尋找到不再使用的變量,并釋放掉它們所指向的內存。

    ?十八、原型鏈

    1. 原型可以解決什么問題

    • ?? ?對象共享屬性和共享方法

    2. 誰有原型

    • 函數擁有:prototype
    • 對象擁有:__proto__

    3. 對象查找屬性或者方法的順序

    • 先在對象本身查找 --> 構造函數中查找 --> 對象的原型 --> 構造函數的原型中 --> 當前原型的原型中查找

    4. 原型鏈
    ?? ?4.1 是什么?:就是把原型串聯起來
    ?? ?4.2 原型鏈的最頂端是null

    ?十九、JS繼承有哪些方式

    方式一: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 );

    方式三:借用構造函數繼承

    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 );

    ?二十、call、apply、bind區別

    共同點:功能一致

    可以改變this指向

    語法: 函數.call()、函數.apply()、函數.bind()

    區別:

    • 1. call、apply可以立即執行。bind不會立即執行,因為bind返回的是一個函數需要加入()執行。
    • 2. 參數不同:apply第二個參數是數組。call和bind有多個參數需要挨個寫。

    場景:

    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)

    ?二十一、sort背后原理是什么?

    V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小于10的數組使用 InsertionSort,比10大的數組則使用 QuickSort。

    之前的版本是:插入排序和快排,現在是冒泡

    原理實現鏈接:https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js

    ***710行代碼開始***

    二十二、深拷貝和淺拷貝

    共同點:復制
    ?

    1. 淺拷貝:只復制引用,而未復制真正的值。

    var arr1 = ['a','b','c','d']; var arr2 = arr1;var obj1 = {a:1,b:2} var obj2 = Object.assign(obj1);

    2. 深拷貝:是復制真正的值 (不同引用)

    var obj3 = {a:1,b:2 } var obj4 = JSON.parse(JSON.stringify( obj3 ));

    //遞歸的形式

    var oldObj = {a: 1,b: 2,arr: ['1', '2', '3']};var newObj = {};function recursion(newObj, oldObj) {for (var k in oldObj) {var item = oldObj[k];if (item instanceof Array) {newObj[k] = [];recursion(newObj[k], item);} else if (item instanceof Object) {newObj[k] = {};recursion(newObj[k], item);} else {newObj[k] = item;}}return newObj;}recursion(newObj, oldObj);newObj.a = '我是你爸爸真偉大'console.log(newObj);console.log(oldObj);

    二十三、localStorage、sessionStorage、cookie的區別

    公共點:在客戶端存放數據

    區別:

    1. 數據存放有效期

    • sessionStorage : 僅在當前瀏覽器窗口關閉之前有效。【關閉瀏覽器就沒了】
    • localStorage? ? ? : 始終有效,窗口或者瀏覽器關閉也一直保存,所以叫持久化存儲。
    • cookie?? ??? ??? ??? ?: 只在設置的cookie過期時間之前有效,即使窗口或者瀏覽器關閉也有效。

    2. localStorage、sessionStorage不可以設置過期時間

    • cookie 有過期時間,可以設置過期(把時間調整到之前的時間,就過期了)

    3. 存儲大小的限制

    • cookie存儲量不能超過4k
    • localStorage、sessionStorage不能超過5M

    ????????****根據不同的瀏覽器存儲的大小是不同的。

    二十四、http狀態碼的了解

    • 2開頭的表示請求成功
      • 200表示一切正常
    • 3開頭的表示重定向
      • 301永久重定向
      • 302臨時重定向
    • 4開頭表示客戶端錯誤
      • 400表示請求報文中存在語法錯誤
      • 403常見的跨域
      • 404請求資源不存在
    • 5開頭表示服務器端錯誤
      • 500表明服務器端在執行請求時發生了錯誤

    二十五、防抖和節流的作用

    共同點:限制函數的執行次數

    防抖:通過setTimeout的方式,在一定的時間間隔內,將多次觸發只執行最后一次觸發;
    節流:減少一段時間的觸發頻率

    ?二十六、var、let、const區別

    var、let、const 共同點都是可以聲明變量的

    區別一:

    • ?? ?var 具有變量提升的機制
    • ?? ?let和const沒有變量提升的機制

    區別二:

    • ?? ?var 可以多次聲明同一個變量
    • ?? ?let和const不可以多次聲明同一個變量

    區別三:

    • ?? ?var、let聲明變量的
    • ?? ?const聲明常量
    • ?? ?var和let聲明的變量可以再次賦值,但是const不可以再次賦值了。

    區別四:

    • ?? ?var聲明的變量沒有自身作用域
    • ?? ?let和const聲明的變量有自身的作用域

    ?二十七、作用域考題

    考題一:let和const沒有變量提升性

    console.log( str );//undefined var str = '你好';console.log( num );//報錯 let num = 10;

    考題二:

    function demo(){var n = 2;if( true ){var n = 1;}console.log( n );//1 } demo();function demo(){let n = 2;if( true ){let n = 1;}console.log( n );//2 } demo();

    考題三:可以修改

    const obj = {a:1 } obj.a = 11111; console.log( obj )const arr = ['a','b','c']; arr[0]= 'aaaaa'; console.log( arr );

    ?二十八、將下列對象進行合并

    方式一:Object.assign

    const a = {a:1,b:4}; const b = {b:2,c:3};let obj1 = Object.assign(a,b); console.log( obj1 );

    方式二:...

    let obj2 = {...a,...b}; console.log( obj2 );

    方式三:自己封裝方法

    function extend( target, source ){for(var key in source){target[key] = source[key];}return target; } console.log( extend(a,b) );

    ?二十九、箭頭函數和普通函數有什么區別?

    1. this指向的問題

    • 箭頭函數中的this只在箭頭函數定義時就決定的,而且不可修改的(call、apply、bind)
    • ****箭頭函數的this指向定義時候、外層第一個普通函數的this

    2. 箭頭函數不能new(不能當作構造函數)
    3. 箭頭函數prototype
    4. 箭頭函數arguments

    ?三十、Promise有幾種狀態

    有三種狀態:

    • pending(進行中)
    • fulfilled(已成功)
    • rejected(已失敗)

    Promise 是es6引入的異步編程解決方案

    ?可以鏈式調用,解決回調地獄的問題

    ?三十一、find和filter的區別??

    區別一:返回的內容不同

    • filter? 返回是新數組
    • find ? 返回具體的內容

    區別二:

    • find? ? 匹配到第一個即返回
    • filter? ?返回整體(沒一個匹配到的都返回)?

    ?三十二、some和every的區別 ?

    • some ?? 如果有一項匹配則返回true
    • every? ? 全部匹配才會返回true

    ?三十三、利用遞歸求斐波那契數列

    function fb(n) {if (n == 0) {return 0;}if (n <= 2) {return 1;}return fb(n - 1) + fb(n - 2);}console.log(fb(9));

    ?三十四、利用遞歸求階乘

    function fn(n) {if (n == 1) {return 1;}return n * fn(n - 1);}console.log(fn(3));

    總結

    以上是生活随笔為你收集整理的js高频面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。