【JS】Function

闭包

  • 只要这个函数调用后没执行完,该执行上下文会一直存在,不会被垃圾回收
  • 闭包:解决外部变量无法访问内部变量,闭包涉及到的变量会一直存在。
  • 如果多人引用,因为函数作用域的独立性,不会互相干扰
  • new Function创建的函数,是全局执行上下文
function test() {
     var i = 0;
     return function () {
         var j = 0;
         ++i, ++j;
         console.log(i * j);
     }
 }
 var f1 = test();
 f2 = test();//独立
 f1();//1
 f1();//2 因为闭包,所以引用变量一直存在
 f2();//1 函数作用域的独立性

防抖(频繁清空定时器)

频繁操作后,只获取最后

t.oninput = debounce(fn, 1000)
function debounce(fn, delay) {
    let time;//闭包变量,一直存在
    return function(){
        //频繁操作,频繁清空计时器
        clearTimeout(time);
        time=setTimeout(() => {
            //...执行代码
        }, delay);
    }
}

节流(开锁,关锁)

频繁操作,有规律的获取(开锁,关锁)

function throttle(fn,wait){
	let time;
    return ()=>{
        if(!time){
        	timer = setTimeout(()=>{//关锁
            	//...执行代码
                timer = null;//开锁
            },delay);
        }
    }
}
function throttle(fn,wait){
	let old=0;
    return ()=>{
        let now=new Date().valueOf();
        if(now-old>wait){
        	//...执行代码
        	old=now;
        }
    }
}

递归

  • 递归必须有一个跳出条件

  • 每一层递归如果需要进行累计操作,需要return一个值,不然就会undefined

  • 函数作用域

    • 会保存当前函数内的信息
    • 每个函数都是独立的
  • 可以使用尾递归进行优化

  • 递归其实是个回溯的过程,从返回的位置往回执行


当一个函数进行嵌套调用时

  • 当前函数被暂停
  • 将当前函数的执行上下文依次入栈

尾递归优化:将每次的结果携带

//优化前
function dg(n){
    if(n===1)return 1;
    return n*dg(n-1)
}
dg(5)
//优化后 O(1)
function dg(n,total){
    if(n===1)return total;
    return dg(n-1,n*total) //将结果携带
}
dg(5,1)

this

  • this是动态的,谁调用this就指向谁

    • 多层调用取决于最近的

    • 没有明确调用者,则为全局调用

  • 箭头函数,this指向外层的this(静态指向)

  • 立即执行函数,this指向全局

修改this

let obj1={
    name:'obj1_name',
    print:function(){
        return()=>console.log(this.name)
    }
}
let obj2={name:'obj2_name'}

obj1.print()() //obj1_name
obj1.print().call(obj2) //obj1_name
obj1.print.call(obj2)() //obj2_name
  • 没有参数时,this指向全局
  • call性能更好
.call(this,参数);  //性能更好
.apply(this,[参数]);      
.bind(this,参数)();  //bind会返回新函数

箭头函数

  • 箭头函数不能使用arguments、super和new.target,但可以使用rest参数访问参数列表
    • arguments是类数组,可迭代对象
  • 箭头函数没有prototype属性不能用作构造函数
  • 箭头函数的this指向其所在作用域(this是静态的)
  • 普通函数可以使用call修改this。但箭头函数不行(因为他根本没有自己的this

展开运算符

rest参数

  • 用于接受函数参数,只能放在末尾,并返回一个数组(arguments是类数组)

    function fn(a,...args){
        console.log(a,args);//1 [2, 3, 4, 5]
    }
    fn(1,2,3,4,5)
    
  • 也可以用于解构赋值

    let [a,...args]=[1,2,3,4,5]
    console.log(a,args);//1 [2, 3, 4, 5]
    

spread语法

  • 将数组 | 字符串 | 对象在语法层面展开
  • 浅拷贝
  • 字符串:展开为字符串数组
  • 函数调用传参fn(...arr)

数组

  • 展开数组[...arr]
  • 数组合并[...arr,...arr1]
  • 将类数组传为数组[...arguments]

对象

  • 展开对象{...obj}

  • 具有iterator接口的对象也可以展开

    var m = new Map();
    m.set(1,1)
    m.set(2,2)
    var arr = [...m] // [[1,1],[2,2]]
    
  • 对象合并{...obj,...obj1}

  • 属性覆盖{...obj,"name":"bob"}


解构赋值

  • 将属性 | 值从对象 | 数组中取出,赋值给其他变量。
  • 解构接收的变量必须声明
  • 可以嵌套解构,只要格式对应就行

数组

  • 解构:var [one, two, three] = [1,2,3];
  • 设置默认值:var [a=5, b=7] = [1];
  • 交换变量值:[a, b] = [b, a];
  • 忽略值:var [a, , b] = f()
  • 使用rest参数:var [a, ...b] = [1, 2, 3]
  • 使用正则解构

对象

  • 解构:var {a, b} = {a: 1, b: 2}
  • 起别名:var {a: A, b: B} = {a: 1, b: 2}
  • 默认值:var {a = 10, b = 20} = {a: 1};

高阶函数

满足以下一种情况:

  • 函数接受的参数还是函数
  • 函数返回的还是函数(闭包)

比如:setTImeout,Promise


函数柯里化

  • 通过函数调用继续返回函数
  • 将多个参数变成单个参数
function(a,b,c){}
//柯里化
function(a){
	return function(b){
		return function(c){
			return a+b+c
		}
	}
}

工厂函数

调用该函数,内部会实例化对象并返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值