call apply bind

本文深入解析JavaScript中call方法的功能与使用技巧,展示如何通过call改变函数执行时的this指向,以及如何传递参数。同时,文章提供了详细的代码示例,帮助读者理解call方法的工作原理和应用场景。
  • call call的特点
  1. 可以改变当前函数this的指向
  2. 让当前函数执行
function fn1(){
    console.log(this)
}
fn1.call()
结果是:window
复制代码

如果传值

function fn1(){
    console.log(this,arguments)
}
fn1.call('jeffywin',1,2)
结果是:jeffywin,Arguments(2)[1,2]
复制代码
function fn1() {
    console.log(1)
}

function fn2() {
    console.log(2)
}
//fn1的this指向fn2,并且让fn1执行
fn1.call(fn2)
结果是:1,this指向fn2

复制代码
原理类似于
Function.prototype.call = function(context) {
  this() //会让当前函数的this指向fn2,fn2执行 
}
fn1.call.call(fn2)
结果是:2
复制代码
Function.prototype.callBind = function(context) {
    context = context ? Object(context) : window
    //context: hello 上下文
    //arguments ['hello',1,2]
    //this = fn1()
    //如果要让this='hello',fn1执行的时候,xxx.fn1() .前面是谁,this就指向谁,这里context上下文就是hello
    //所以让context转成对象,(字符串不能.fn1())再挂上fn1(),这样this就指向hello
    //eval('context.fn('+args+')')执行的时候,因为context.fn = fn1,所以context.fn()执行相当于fn1执行,this指向context,也就是hello
    context.fn = this //{}.fn = fn1  context.fn=fn1
    let args = []
    for(let i=1;i<arguments.length;i++) {
        args.push('arguments['+i+']')
    }
    //context.fn(arguments[1],arguments[2])
    //eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
    let r = eval('context.fn('+args+')')
    
    delete context.fn
    return r 
}
fn1.callBind('hello',1,2)

复制代码
//apply实现
Function.prototype.applyBind = function(context,args) {
    context = context ? Object(context) : window
    context.fn = this 
    if(!args) {
       return context.fn()
    }
    let r = eval('context.fn('+args+')')
    delete context.fn
    return r 
}

fn1.applyBind('hello',[1,2])

复制代码

//1) bind方法可以绑定this指向 绑定参数
//2) bind方法返回一个绑定后的函数 原理:高阶函数
//3) 如果绑定的函数被new了,当前函数的this就是当前的实例
//4) new 出来的结果可以找出原有类的原型
Function.prototype.bindMy = function (context) {
  let that = this;
  let bindArgs = Array.prototype.slice.call(arguments, 1);//['猫']
  //this:fn context:obj
  function Fn(){}
  function fBound() {
    let args = Array.prototype.slice.call(arguments)
    return that.apply(this instanceof fBound ? this : context, bindArgs.concat(args))
  }
  Fn.prototype = this.prototype
  fBound.prototype = new Fn()
  return fBound
}

let obj = {
  name: 'jeffywin'
}

function fn(name, age) {
  console.log(this.name + '养了一只' + name + age + '岁了')
}
fn.prototype.flag="哺乳类"
let bindFn = fn.bindMy(obj, '猫')
//bindFn(9)
let i = new bindFn(9)
console.log(i.flag)


复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值