1.讲一下闭包相关知识,和普通函数有什么区别
闭包是什么:JS中内层函数可以访问外层函数的变量,外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。
闭包的好处:
隔离作用域,保护私有变量;有了闭包才有局部变量,要不然都是全局变量了。
让我们可以使用回调,操作其他函数内部;
变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期;
闭包的弊端:内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。
解决办法:无法自动销户,就及时手动回收,使用后将函数的引用赋null。
闭包深入理解
那如果有ab两个函数,b作为a的参数传入,a中要怎么使用b呢 ,回答了callback函数 面试官说也确实可以实现
另外的方法:
//定义一个add函数
function add(){
console.log(“这是加法函数!”);
}
//定义一个计算函数counter,并将函数method作为参数,并调用了method()
function counter(method){
method();
}
//调用了counter()函数,并将函数add作为参数传进去
counter(add);
//运行的结果为:这是加法函数!
总结:
①. 将函数作为另一个函数的参数使用,只需要在调用另一个函数时,将函数作为参数传递进去。另一个函数已经完成对传进来函数的调用。
②. 同时需要注意的是:在js中,函数也是对象,所以是引用传地址,函数名就是指向该对象的地址,所以将函数作为参数的时候,只需要将函数名写入即可。
特别说明:这里的函数作为另一个函数的参数使用,也就是闭包的使用,可以访问函数内部的变量。
参考文档
2.怎么理解css的选择器权重问题 如果没有这个权重设定可以吗 会出现什么问题
从样式选择器看权重优先级:important > 内嵌样式 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪对象 > 继承 > 通配符。
important的权重为1,0,0,0
ID的权重为0,1,0,0
类的权重为0,0,1,0
标签的权重为0,0,0,1
伪类的权重为0,0,1,0
属性的权重为0,0,1,0
伪对象的权重为0,0,0,1
通配符的权重为0,0,0,0
当权重不同时,权重高的显示;当权重相同时,后写的样式起作用,我回答可以完成一些用户交互的样式切换效果
3.手写冒泡排序,并且讲思路
// 编写方法,实现冒泡
var arr = [29,45,51,68,72,97];
//外层循环,控制趟数,每一次找到一个最大值
for (var i = 0; i < arr.length - 1; i++) {
// 内层循环,控制比较的次数,并且判断两个数的大小
for (var j = 0; j < arr.length - 1 - i; j++) {
// 白话解释:如果前面的数大,放到后面(当然是从小到大的冒泡排序)
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);//[2, 4, 5, 12, 31, 32, 45, 52, 78, 89]
参考博客
4.深浅拷贝问题
、深拷贝与浅拷贝的区别?
拷贝的层级不同,深拷贝是指每一层数据的改动都不会影响原对象和新对象,浅拷贝只有第一层的属性变动不互相影响,深层的数据变动还会互相影响。
2、实现拷贝的方法有哪些?
浅拷贝:数组可以用拓展运算符[...arr],或者slice().浅拷贝对象可以用Object.assign({},obj)
深拷贝:JSON.parse(JSON.stringify(obj)),或封装递归方法,或使用第三方库的方法,比如 JQuery的$.extend({},obj),或者lodash 的cloneDeep
3、JSON.parse(JSON.stringify(obj))处理的缺点?
如果对象中有属性是function或者undefined,处理后会被过滤掉;
如果属性值是对象,且由构造函数生成的实例对象,会丢弃对象的constructor;
5.原型和原型链,有什么作用
原型:在js中,每一个对象(函数也是对象)都有一个特殊的属性叫做原型(prototype),它指向另一个对象,这个对象(Test.prototype)被称为原型对象, 原型对象是用来共享属性和方法的。
(1)原型对象有一个constructor属性指向构造函数本身(Test)。
(2)原型对象是一个普通的对象,它包含属性和方法。
(3)原型对象的属性和方法会被继承到所有通过原型链与它相连的对象。
简单来说,原型对象是一个普通对象,属性和方法会被继承到其他对象,而每个对象都有一个原型(prototype),用来继承其他对象的属性和方法。
原型链:指一些原型通过__proto__指针构成的链表,一个原型链可以为想共享原型链中数据的对象服务,用于实现JavaScript中的继承机制。
(原型链指针) 原型链中涉及到的指针:
每个对象都有一个__proto__指针来访问对象的原型
每个原型都是一个用于实现继承的对象,除了有__proto__指针之外,还有constructor指针指向构造函数
每个函数都是一个对象,除了有__proto__指针之外,还有prototype指针指向与之关联的原型对象,prototype的指向和__proto__指向不一定相同。
6.讲一个比较好的项目或者是项目中的收获
7.假如我们要做一个表单,需要校验,是前端校验还是后端校验好,
回答了都可以做,如果前端做了校验,但后端拿到的数据还是有问题怎么办 比如伪造了一个请求 如果前端做了后端还需要吗 我说最好是要 前端只能做简单的用户交互熟输入的一些校验没办法判断接口类的校验
8.这个表单如何实现
面试前刚好做个vue3的后台管理项目, 就讲了大概思路 大家看个组件库就会了
9.点击按钮提交数据,然后按钮置灰,但是点击够快可能会多次提交,影响业务,怎么处理
回答了防抖
思路:在用户多次点击按钮时,我们选择保留最后一次事件触发,即在点击到事件触发这段时间,如果用户再点击,则将上一次点击的操作取消,而等待执行新点击的操作,以此类推;
参考文献:手写防抖函数
10.获取两个接口数据,但两个接口数据互相有依赖,b接口需要a接口数据去做一些逻辑处理,你遇到这种问题怎么处理
回答了使用async await 直到接收到a接口数据再去请求b接口
问还有没有其他方法 回答了没想到
问能不能通过同步请求两个接口 判断接口返回code码是200 成功的
11.开发的时候遇到没用过的插件或者技术栈 一般怎么学习
这个问题就属于开放题,可以自由发挥
我当时回答的是官方文档、掘金、github以及一些论坛和社区
刚好在踩坑nvm,于是就把这个踩坑经历和面试官分享了
后续的就是对公司情况的一些了解,以及直接和老板谈薪了,其实一开始还做了一轮笔试,但是题目已经记不太清了,目前已经顺利入职啦(对于一年多没从事开发行业的我来说,已经很满意了~~),接下来就是技术沉淀 沉淀 再沉淀 最后也祝各位读者也能顺利入职!!!