坐标:成都 段位:中级
ps:以下是我面试问题的整理,持续更新。有需要的小伙伴可以看看
CSS 1.固定定位,绝对定位,相对定位
①固定定位:
position:fixed 相对于它最近的定位父元素定位,脱离文本流
②绝对定位:
position:absolute 相对于它最近的定位父元素定位,脱离文本流
③相对定位:
position:relative 相对于原来位置定位,不脱离文本流
2.一个布局,左边固定,右边自适应如何书写
1.左边position:absolute,右边margin:left
2.左边float
3.左右float,右边使用负边距
4.flex布局
JS 3.let const var的区别
1.变量提升
使用var时,这个关键字声明的变量会自动提升到其所处作用域的顶部
使用let时,let声明的变量不会在作用域中被提升(暂时性死区,const一样)
2.声明作用域
使用var操作符定义的变量会成为包含它的函数的局部变量,var声明的范围是函数作用域
使用let声明的范围是块级作用域(const一样)
3.重复定义
var可以被重复定义;let,const不能被重复定义;
且const不能被重复赋值,如果是内部属性可以。比如
const obj = {name:'js'} obj.name = 'ss' 是可以的
补充:
1.对于let这个新的ES6声明关键字,不能依赖条件声明模式。
2.for循环中的let声明,javaScript引擎在后台会为每个迭代循环声明一个新的迭代变量,也就是循环过程中每个迭代变量的值。
3.for循环中不能使用const作为变量,因为迭代变量会自增
for (const i = 0; i < 10; ++i) {} // TypeError:给常量赋值
4.推荐使用const,let次之,var不推荐
4.判断一个值是null还是undefined
1.使用typeof
2.将这个值变为字符串判断
5.Object.assgin()的使用
概念:Object.assgin:主要是将所有可枚举属性的值从一个或多个源对象复制到目标对象,同时返回目标对象。
用法:Object.assign(target, ...sources)
其中 target 是目标对象,sources 是源对象,可以有多个,返回修改后的目标对象 target。
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后来的源对象的属性将类似地覆盖早先的属性
6.深浅拷贝的概念,且深拷贝的方式有哪些
1.首先区别赋值和赋址的概念。如果两个对象是赋值的情况,改变一个值另一个不会被改变。如果两个对象是赋址的情况,改变一个另一个跟着
改变.
2.浅拷贝的概念:创建一个新对象,这个对象有着原始对象属性值得一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址(赋址拷贝) ,
3.深拷贝得概念:可以理解为赋值拷贝。
4.深拷贝得常用方式:Object.assgin(),JSON.stringfy和JSON.parse,jq得extend方法,lodash的cloneDeep方法,递归的方式。
注意:Object.assgin()当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就
是浅拷贝。
7.防抖节流
函数节流概念:函数节流指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 无视后来产生的函数调用请求,也不会
延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视后来产生的函数调用请求,以此类推。
节流使用场景:window.onresize() 事件、mousemove 事件、上传进度等情况
实现方案:
1.是用时间戳来判断是否已到执行时间,记录上次执行的时间戳,然后每次触发事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间
隔是否已经达到时间差(Xms) ,如果是则执行,并更新上次执行的时间戳,如此循环。
2.是使用定时器,比如当 scroll 事件刚触发时,打印一个 hello world,然后设置个 1000ms 的定时器,此后每次触发 scroll 事件触发回
调,如果已经存在定时器,则回调不执行方法,直到定时器触发,handler 被清除,然后重新设置定时器。
函数防抖概念:防抖函数 debounce 指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。假如我们设置了一个等待时间
3秒的函数,在这 3 秒内如果遇到函数调用请求就重新计时 3 秒,直至新的 3 秒内没有函数调用请求,此时执行函数,不然就以此类推重新计
时。
防抖使用场景:可能频繁触发的场景,比如一个按钮在一个时间段被多次点击
原理及实现:实现原理就是利用定时器,函数第一次执行时设定一个定时器,之后调用时发现已经设定过定时器就清空之前的定时器,并重新设
定一个新的定时器,如果存在没有被清空的定时器,当定时器计时结束后触发函数执行。
8.事件委托,事件冒泡,事件捕获
1.事件委托
当我们要给每个元素绑定一个事件,然后遍历,很费性能。此时我们直接给父元素绑定即可。解决几个问题:
遍历带来的性能问题;动态添加的元素,必须使用事件委托;事件委托是通过事件冒泡实现的,如果子级元素(e.stopPropagation)阻止
了事件冒泡,那么事件委托失效
2.事件冒泡
就是点击最里面的元素,会触发父级元素的方法
3.事件捕获
就是点击父级元素,会触发子级元素的方法
9.事件循环
内容太多,直接看大佬的回答吧 点击阅读
10.arguments
概念:arguments 是一个对应于传递给函数的参数的类数组对象。
使用:arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给
函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:
arguments[0]
arguments[1]
arguments[2]
如果调用的参数多于正式声明接受的参数,则可以使用arguments对象。这种技术对于可以传递可变数量的参数的函数很有用。使用
arguments.length来确定传递给函数参数的个数,然后使用arguments对象来处理每个参数。要确定函数签名中(输入)参数的数量,请使
用Function.length属性。
11.以下代码输出什么
setTimeout(() => { console.log(0) })
for (let i = 0; i < 5; i++) {
console.log(i + 1)
}
输出:1,2,3,4,5,0
先同后异原理,setTimeout是异步所以延后执行,for循环内部使用let,let因为暂时性死区所以是依次打印
参考资料: 1.zhuanlan.zhihu.com/p/87684858 2.muyiy.cn/blog/7/7.2.…