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页!!