1.说一下 callee 和 caller
1.首先说一个概念就是arguments 在函数中 包含所有被传入的实参 ,类似于一个数组 可以arguments[0]这种形式访问
也可以获取长度 。当时箭头函数没有arguments
2.arguments上面有个属性callee,callee类似于一个指针 ,指向当前函数 ,一般情况下我们都用于函数的递归
// "use strict" function getName(arr) { console.log(arguments); console.log(arguments[0]);//1 console.log(arguments.length);//5 console.log(arguments.callee);//ƒ getName(arr) //严格模式下会报错 console.log(arguments.caller);//undefined } getName(1,2,3,4,5)
3.一个函数调用另一个函数的时候 ,我们可以用functionName.caller属性 显示调用者函数的上下文。最顶层函数的caller是null
function outer() { inner(); } function inner() { console.log(inner.caller);//f outer() //严格模式下会报错 } outer();
4.但是在严格模式下 arguments.callee会报错 而给函数的.caller赋值也会报错。
2. 如何避免回调地狱?
1.promise
promise就是为了解决回调地狱的问题的,将回调地狱转成链式调用 。
promise就相当于一个容器 ,里面存放了未来可能发生的结果(请求返回的结果)。promise有三种状态 ,pending,resolve,reject 。可以从pending到resolve 或者从pending到reject,状态一旦被触发,就会将值缓存下来,并尝试触发回调函数,并且回调函数触发后会立即被销毁。
2.async和await
async 和await 是 将异步代码以同步代码的形式表达出来的 ,他返回的是一个promise函数。她其实是generator函数的语法糖,将*变现为async 将 yield替换为await 。
3.谈谈防抖和节流
防抖:
是在一个时间间隔内多次触发一个事件,每次触发都会重新计时
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
例如:输入框搜索
节流:
是指在在一个时间间隔内多次触发一个事件,只有第一次生效,其他的都不生效 。
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
例如:点击按钮
4. 0.1 + 0.2 === 0.3 ??
0.1和0.2在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,
相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成 0.30000000000000004。
其实本质就是 二进制模拟十进制进行计算时 的精度问题
解决办法:
1.转为 整数进行计算 但是对大数挺不友好的 。
( 0.1* 10 + 0.2 * 10 ) /10
2.转为 toFixed(2)这种
(0.1 + 0.2).toFixed(2),但是转为的是字符串 0.3 ===>不推荐
3.浏览器自带的这个应该挺好用的 还不用考虑兼容性
Number(new Intl.NumberFormat('en-US').format(0.1 + 0.2))
4. 利用第三方库 --(没试验过)
Math.js ....
5.垃圾回收机制
1、标记清除(Mark-Sweep)
原理: 给当前程序中的所有变量标记一个二进制数为0(二进制数最快),当使用变量的时候将当前变量的标记置为1 ,最后程序结束的时候将所有为0的变量清除 ,再将剩余变量置为0 开始下一次程序运行
缺点:容易出现内存碎片
2、引用计数
跟踪记录每个变量值被使用的次数,如果一个引用类型的值给一个声明的变量赋值,则将这个引用类型的值的引用次数为1,如果同一个值被又被赋值给另一个变量,则引用计数再加1,如果之前被赋值的变量值变更成了其他引用类型,则原本的引用类型引用计数减1,如果这个引用类型的引用计数为0时表示,此时为不可达状态,浏览器垃圾回收器就讲此类型占用的空间进行回收掉(此处是实时的,当计数变为0既会被立即回收)。
缺点:空间浪费 ,循环引用无法回收