什么是开包和闭包
开包:开包也可以叫函数柯里化,是将接收多个参数的函数转换成一系列使用单个参数的函数
function add(x, y) {
return x + y
}
function addToX(x) {
return function (y) {
return add(x, y)
}
}
const addFive = addToX(5);
addFive(2); // 7
闭包 :
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收,会永远留驻在内存中
闭包优点:长时间储存变量在内存中,减少全局变量的污染,加强封装性
闭包缺点:占用更多的内存导致内存泄漏,或性能下降
闭包不是回调,回调也不是闭包,回调是函数内执行另一个函数,闭包是函数内返回另一个函数,且返回了父级函数的作用域变量
垃圾回收机制:简单的说,当一个函数被执行完后,其作用域会被收回
function counter() {
let count = 0
return () => {
return ++count
}
}
const c = counter()
console.log(c()) //1
console.log(c()) //2
console.log(c()) //3
原型链
- 原型:portoType属性就是函数的原型
- 原型链:所有对象都有原型,而原型本身就是对象,所以原型也有自己的原型对象,就形成了原型链
- 如果对象本身没有属性,就会去原型链上找
- object原型对象的原型值为null
防抖和节流
- 防抖:触发事件后在N秒内只执行一次,如果再次触发则重新计算函数执行时间(每多少秒内只能执行一次,再次点击重新算时间)
- 节流:每次触发事件后的时间间隔至少要大于等于N秒,不会重置计时(每多少秒可以触发一次)
递归
什么是递归
- 自身调用自身
- 至少应该有一个结束条件
使用场景
- 多层级结构,并且每个层级大致相同,而且前后还有关联性
递归比普通函数效率低,日常还是少用吧
function walk(step){
if(step == 0){
console.log('结束了')
}else{
step--
walk(step)
}
}
walk(100) //默认传了100
去重
- new Set()
let arr = [1,2,3,4,5,1,2,3,4,5,6]
let setArr = new Set(arr)
console.log(setArr) //返回set数据结构 Set(3) {1,2,3,4,5,6,7}
//es6的 ... 运算符
console.log([...setArr]) //输出 [1, 2, 3, 4, 5, 6]
console.log(...setArr) //输出 1, 2, 3, 4, 5, 6
- indexOf
let arr1 = [1,2,3,4,5,1,2,3,4,5,6]
let arr2 = []
for(let i in arr1){
if(arr2.indexOf(arr1[i]) === -1){ //如果数组中没有当前数值,indexOf 则返回-1,
arr2.push(arr1[i])
}
}
console.log(arr2)
- 双层循环,外层循环数组1,内层循环数组2,数组2中有则跳过,没有则push