web前端工程师这些年被问烂了的面试题JavaScript

Posted 柠檬20

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web前端工程师这些年被问烂了的面试题JavaScript相关的知识,希望对你有一定的参考价值。

可乐伢


文章目录


前言

提示:大多数人会觉得基础很简单。忽略。但如果js基础你回答的不好,那么你在面试官心中的心中就已经是不太符合了。大佬请忽略此提示


一、基础模块

1.js数据类型判断

a.类型判断

基本数据类型:Undefined、Null、Boolean、Number、String,Symbol
引用数据类型:对象(Object)、数组(Array)、函数(Function)。

  • typeof

     					console.log(typeof bool); //boolean
     					console.log(typeof num);//number
     					console.log(typeof str);//string
     					console.log(typeof und);//undefined
     					console.log(typeof nul);//object
     					console.log(typeof arr);//object
     					console.log(typeof obj);//object
     					console.log(typeof fun);//function
     					console.log(typeof s1); //symbol
     					console.log(typeof NaN);// number
     					console.log(typeof false );// boolean
     		
       typeof可以识别出基本类型boolean,number,undefined,string,symbol,但是不能识别null。
     不能识别引用数据类型,会把null、array、object统一归为object类型,但是可以识别出function
     所以typeof可以用来识别一些基本类型。
    
  • instanceof

     				console.log(bool instanceof Boolean);// false
     				console.log(num instanceof Number);// false
     				console.log(str instanceof String);// false
     				console.log(und instanceof Object);// false
     				console.log(nul instanceof Object);// false
     				console.log(arr instanceof Array);// true
     				console.log(obj instanceof Object);// true
     				console.log(fun instanceof Function);// true
     				console.log(s1 instanceof Symbol);// false
     
       从结果中看出instanceof不能识别出基本的数据类型 number、boolean、string、undefined、
     unll、symbol。
       但是可以检测出引用类型,如array、object、function,同时对于是使用new声明的类型,它还可
     以检测出多层继承关系
    
  • constructor

     				console.log(bool.constructor === Boolean);// true
     				console.log(num.constructor === Number);// true
     				console.log(str.constructor === String);// true
     				console.log(arr.constructor === Array);// true
     				console.log(obj.constructor === Object);// true
     				console.log(fun.constructor === Function);// true
     				console.log(s1.constructor === Symbol);//true
     				
       null、undefined没有construstor方法,因此constructor不能判断undefined和null。但是他
    是不安全的,因为contructor的指向是可以被改变。
    
  • Object.prototype.toString.call

     		console.log(Object.prototype.toString.call(bool));//[object Boolean]
     		console.log(Object.prototype.toString.call(num));//[object Number]
     		console.log(Object.prototype.toString.call(str));//[object String]
     		console.log(Object.prototype.toString.call(und));//[object Undefined]
     		console.log(Object.prototype.toString.call(nul));//[object Null]
     		console.log(Object.prototype.toString.call(arr));//[object Array]
     		console.log(Object.prototype.toString.call(obj));//[object Object]
     		console.log(Object.prototype.toString.call(fun));//[object Function]
     		console.log(Object.prototype.toString.call(s1)); //[object Symbol]
     		
      此方法可以相对较全的判断js的数据类型。至于在项目中使用哪个判断,还是要看使用场景,具体的选
    择,一般基本的类型可以选择typeof,引用类型可以使用instanceof。
    

Symbol是干嘛的:

Symbol是 ES6 引入了一种新的原始数据类型 ; Symbol不是直接存储数据的, 而是, 作为一个独一无二的key, 放置数据的, 防止数据因为重复, 无法存进数据对象中,例如: obj中,存入key为1和‘1’的值, 后面的会把前面的覆盖掉.

b.数组判断

  • 通过Object.prototype.toString.call()做判断(Object.prototype.toString.call(obj).slice(5,-1) === ‘Array’)

  • 通过instanceof做判断(obj instanceof Array)

  • 通过ES6的Array.isArray()做判断(Array.isArrray(obj))

  • 通过Array.prototype.isPrototypeOf(Array.prototype.isPrototypeOf(obj))

  • 通过原型链做判断(obj._ proto _ === Array.prototype)

2.js数组方法(谨记哪些能改变,哪些不能改变原数组)

a)不会改变原数组哦:

  • concat()—连接两个或更多的数组,并返回结果。

  • every()—检测数组元素的每个元素是否都符合条件。

  • some()—检测数组元素中有一个元素满足条件,则返回true , 剩余的元素不会再检测。。

  • filter()—检测数组元素,并返回符合条件所有元素的数组。

  • indexOf()—搜索数组中的元素,并返回它所在的位置。

  • join()—把数组的所有元素放入一个字符串。

  • toString()—把数组转换为字符串,并返回结果。

  • lastIndexOf()—返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。

  • map()—通过指定函数处理数组的每个元素,并返回处理后的数组。

  • slice()—选取数组的的一部分,并返回一个新数组。

  • valueOf()—返回数组对象的原始值。

b)会改变原数组哦:

  • pop()—删除数组的最后一个元素并返回删除的元素。

  • push()—向数组的末尾添加一个或更多元素,并返回新的长度。

  • shift()—删除并返回数组的第一个元素。

  • unshift()—向数组的开头添加一个或更多元素,并返回新的长度。

  • reverse()—反转数组的元素顺序。

  • sort()—对数组的元素进行排序。

  • splice()—用于插入、删除或替换数组的元素。

  • fill()—方法用于将一个固定值替换数组的元素

  • 注意:修改数组,这就导致元素移动,下标也会改变

3.JS 中 == 和 === 区别是什么?

 let a = 1
 let b = '1'
 console.log(a==b)//true  不同类型间比较,转化成同一类型后的值”看“值”是否相等,
 console.log(a===b)//false  因为类型不同,=== 结果为false。
 注意:对于Array,Object等高级类型,==和===没有区别

4. JS中的Array.splice()和Array.slice()方法有什么区别

var arr=[0,1,2,3,4,5,6,7,8,9];//设置一个数组
console.log(arr.slice(2,7));//2,3,4,5,6
console.log(arr.splice(2,7));//2,3,4,5,6,7,8
//由此我们简单推测数量两个函数参数的意义,
slice(start,end)第一个参数表示开始位置,第二个表示截取到的位置(不包含该位置)
splice(start,length)第一个参数开始位置,第二个参数截取长度

5. JS中的for···in和for···of的区别

1、推荐在循环对象属性的时候,使用for…in,在遍历数组的时候使用for…of。
2、for…in 循环出的是 key,for…of 循环出的是 value
3、for…of 不能循环普通的对象,需要通过Object.keys()来强制使用

6、js防抖和节流

在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。

防抖 如果你在监听滚动事件,假设两秒以内用户在不断的平凡的触发onScroll事件,只有用户暂停滚动后,才会去执行响应的操作,如下

// 函数防抖
var timer = false;
document.getElementById("xxxx").onscroll = function()
    clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
    timer = setTimeout(function()
        console.log("函数防抖");
    , 300);
;

定时器实现节流

// 节流throttle代码(定时器):
var throttle = function(func, delay)             
    var timer = null;            
    return function()                 
        var context = this;               
        var args = arguments;                
        if (!timer)                     
            timer = setTimeout(function()                         
                func.apply(context, args);                        
                timer = null;                    
            , delay);                
                    
            
        
function handle()             
    console.log(Math.random());        
        
window.addEventListener('scroll', throttle(handle, 1000));

7、js深拷贝

function kele (Obj) 
  var kl;
  if (Obj instanceof Array) 
    kl= [];  //创建一个空的数组 
    var i = Obj.length;
    while (i--) 
      kl[i] = kele (Obj[i]);
    
    return kl;
   else if (Obj instanceof Object) 
    kl= ;  //创建一个空对象 
    for (var k in Obj)   //为这个对象添加新的属性 
      kl[k] = kele (Obj[k]);
    
    return kl;
   else 
    return Obj;
  

二、进阶模块

1.JS哪些操作会造成内存泄露

  • a. 意外的全局变量引起的内存泄露
  • b . 闭包引起的内存泄露.
  • c. 没有清理的DOM元素引用
  • d. 被遗忘的定时器或者回调
  • e. 子元素存在引起的内存泄露

2.是否可以在JS中执行301重定向?

  • JS完全运行在客户端上。301是服务器作为响应发送的响应代码。因此,在JS中不可能执行301重定向。

3.JS中的宿主对象与原生对象有何不同?

  • 宿主对象:这些是运行环境提供的对象。这意味着它们在不同的环境下是不同的。例如,浏览器包含像windows这样的对象,但是Node.js环境提供像Node List这样的对象。

  • 原生对象:这些是JS中的内置对象。它们也被称为全局对象,因为如果使用JS,内置对象不受是运行环境影响。

4、window的onload事件和domcontentloaded

window.onload:
当一个资源及其依赖资源已完成加载时,将触发onload事件。

document.onDOMContentLoaded:
当初始的html文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架的完成加载。
区别:
①onload事件是DOM事件,onDOMContentLoaded是HTML5事件。
②onload事件会被样式表、图像和子框架阻塞,而onDOMContentLoaded不会。
③当加载的脚本内容并不包含立即执行DOM操作时,使用onDOMContentLoaded事件是个更好的选择,会比onload事件执行时间更早。

5、说一下JS的同源策略?

同源策略是客户端脚本(尤其是javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。

这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议:指一段脚本只能读取来自同一来源的窗口和文档的属性。

为什么要有同源策略

如果没有同源策略,浏览器一些正常功能可能都会受到影响,ajax太灵活了,各种请求说法就发,如果没有同源策略的限制,发到哪里都行,只要你构造好参数和请求路径,那人人都是黑客了,这样会导致各种敏感数据的泄露。

同源策略的缺点

它影响了与BOM,DOM间的交互。如:不可以访问不同来源的任何页面的document对象,也就是说不能访问其中任何DOM结构。

** 点我查看跨域的解决方案**

6、插入几万个 DOM,如何实现页⾯不卡顿?

DOM 是属于渲染引擎中的东⻄,性能上的损耗比较大。

解决办法:虚拟滚动( virtualized scroller )

这种技术的原理就是只渲染可视区域内的内容,⾮可视区域的那就完全不渲染了,当⽤户 在滚动的时候就实时去替换渲染的内容。

7、js脚本延迟加载的几种方式?

(1)defer属性

<script src="easyliao.js" defer> </script>

1:不会阻塞页面后续处理
2:所有的defer脚本保证是按顺序依次执行的

(2)async属性

<script src="easyliao.js" async> </script>

1:作用和defer类似,但是它将在下载后尽快执行,不能保证脚本会按顺序执行。它们将在onload
   事件之前完成。
2:可以同时使用 async 和 defer,这样IE 4之后的所有IE 都支持异步加载

(3)动态创建DOM方式

<script type="text/javascript">
  function downloadJSAtOnload() 
   var element = document.createElement("script");
   element.src = "defer.js";
   document.body.appendChild(element);
  
  if (window.addEventListener) //添加监听事件
   window.addEventListener("load",downloadJSAtOnload, false); //事件在冒泡阶段执行
  else if (window.attachEvent)
   window.attachEvent("onload",downloadJSAtOnload);
  else
   window.onload = downloadJSAtOnload;
</script>

(4)setTimeout

   <script >
      setTimeout(() => 
        aaa();
      , 10000);
      function aaa()
        let script = document.createElement("script");
        script.src="//scripts.easyliao.com/xxxxx/xxxxx/lazy.js";
        script.id="easyliao"
        document.body.append(script);
      
</script>

 就是延迟加载js,让页面先加载出来

总结

扎实的基本功,会让你事半功倍!

感谢大佬们的支持!!!

以上是关于web前端工程师这些年被问烂了的面试题JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

耗时一个月,我把问烂了的网络安全2023年必考面试题总结了一下

面了6家大厂,我把问烂了的《Java八股文》打造成3个PDF。共1700页

面了6家大厂,我把问烂了的《Java八股文》打造成3个PDF。共1700页!!

收到6家大厂offer,我把问烂了的《Java八股文》打造成3个PDF。共1700页!!

面了6家大厂,我把问烂了的MySQL常见面试题总结了一下(带答案,万字总结,精心打磨,建议收藏)

高频面试题-JDK源码篇(HashMap)