call,apply,bind的区别&&new的实现原理&&防抖和节流

一、call,apply,bind

  • call,apply,bind都是用来改变this指向的。
区别:

1.call用逗号分隔传递参数
用法:函数名.call(目标对象obj,参数1,参数2,…)
2.apply参数用数组的形式传递
用法:函数名.apply(目标对象,[参数1,参数2,…])
3.bind用逗号形式传参
用法:getName.bind(obj,‘李四’,25,‘上海’)() 或
getName.bind(obj)(‘王五’,25,‘北京’)

  • 函数是否被执行:cal和apply是直接调用函数;
    bind是返回函数本身,如果要执行,必须再后面再加()调用
call的实现原理:
  • call是基于函数实现的
  • 给作用的目标对象添加一个临时函数,处理赋值操作
  • 接收参数处理
  • 最后再删除这个临时函数

代码实现:

Function.prototype.call2 = function (context) {
    //目标对象
    context = context || window;
    //this===实例化的函数,函数本质上也是对象
    //给context添加一个临时函数
    context.fn = this;
    //接收参数处理  arguments
    console.log('arguments:',arguments)
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
       // ["arguments[0]", "arguments[1]", "arguments[2]"]
        args.push('arguments['+i+']')
       // args.push(arguments[i])
    }
     //传参执行context.fn()函数
     eval('context.fn(' + args + ')')
    //删除临时函数
    delete context.fn   
}
apply实现的原理:
Function.prototype.apply2 = function (context,arr) {
    //目标对象
    context = context || window;

    //this===实例化的函数,函数本质上也是对象
    //给context添加一个临时函数
    context.fn = this;

    if (!arr) {
        context.fn()
    } else {
        //接收参数处理  arguments
        var args = [];
        for (var i = 0; i < arr.length; i++) {
        // ["arguments[0]", "arguments[1]", "arguments[2]"]
            args.push('arr['+i+']')
        // args.push(arguments[i])
        }

        //传参执行context.fn()函数
        eval('context.fn(' + args + ')')
     }
    //删除临时函数
    delete context.fn
}

二、new的实现原理

new的特点:

  • new 一个构造函数,会自动reutrn一个实例化对象
  • new完的实例化对象proto___自动指向构造函数的prototype
  • new构造函数传参自动赋值给当前实例化对象

三、防抖和节流

1、防抖: 在固定的时间内没有触发事件,会在固定时间结束后触发,如果固定时间内触发事件了,会在延长固定时间再触发;防抖主要利用定时器实现。

代码实现:

//用定时器实现防抖
function debounce(func,wait) {
    var timer=null;
    return function() {
    //保存当前调用的dom对象
     var _this=this;
     //保存事件对象
     var args=arguments;
     clearTimeout(timer)
     timer=setTimeout(function() {
         func.apply(_this,args)
     },wait)
    }
}
2、节流:无论在固定时间内是否有事件触发,都会按照固定时间规律触发;具体实现有两种方法(时间戳和定时器);

代码实现:

//时间戳版本实现节流
function throttle(func,wait) {
    //定义初始时间
    var oldTime=0;
    return function() {
        var _this=this;
        var args=arguments;

        //当前时间戳
        var newTime=+new Date();

        //判断用当前时间减去旧的时间,如果大于wait指定的时间就会触发
        if(newTime-oldTime>wait) {
            //执行触发的函数
            func.apply(_this,args)
            //将旧时间更新
            oldTime=newTime;
        }
    }

定时器代码实现:

//时间戳版本实现节流
function throttle(func,wait) {
    var timer=null;
    return function() {
        var _this=this;
        var args=arguments;
       if(!timer) {
            timer=setTimeout(function() {
                timer=null;
                func.apply(_this,args)
            },wait)
       }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值