call, apply与bind

本文详细解释了JavaScript中的call(),apply(),和bind()方法的应用场景,包括如何改变函数的this指向,以及它们的代码实现。通过实例展示了如何在子类构造函数中使用apply()继承父类属性,和bind()用于创建绑定函数以固定this值。
摘要由CSDN通过智能技术生成

原文链接:call ,apply和bind方法 详解

1. call ,apply 和 bind 应用场景

1.1. call ,apply

  • call 和 apply 方法都是将函数的 this 指向 call 与 apply 函数的第一个参数。

  • call()方法接受的语法和作用与apply()方法类似,只有一个区别就是call()接受的是一个参数列表,而apply()方法接受的是一个包含多个参数的数组。

  • 二者都是函数对象Function的方法,且第一个参数都是要绑定对象的上下文

/*定义一个人类*/  
    function Person(name,age)  
    {  
        this.name=name;  
        this.age=age;  
    }  
    /*定义一个学生类*/  
    functionStudent(name,age,grade)  
    {  
        Person.apply(this,arguments);  //Person.call(this,name,age);
        this.grade=grade;  
    }  
    //创建一个学生类  
    var student=new Student("zhangsan",21,"一年级");  
    //测试  
    alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);  
    //大家可以看到测试结果name:zhangsan age:21  grade:一年级  
    //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处. 

1.2. bind

  • bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,当然这是绑定哦,不是像call、apply一样直接执行,apply要执行的话还得自己调用。
  • bind()函数会创建一个新的绑定函数,这个绑定函数包装了原函数的对象。调用绑定函数通常会执行包装函数。
this.x = 9; //this指向全局的window对象
var module = {
    x: 81,
    getX: function(){return this.x;}
};

console.log(module.getX()); //81

var retrieveX = module.getX;
console.log(retrieveX()); //9,因为函数是在全局作用域中调用的

// 创建一个新函数,把this绑定到module对象
// 不要将全局变量 x 与 module 的属性 x 混淆
var boundGetX = retrieveX.bind(module);
console.log(boundGetX()); //81

2. call,apply 与 bind 代码实现

  • call
// call和apply实现方式类似,只是传参的区别
// 基本思想是把fn.call(obj,args)中的fn赋值为obj的属性,然后调用obj.fn即可实现fn中this指向的改变
Function.prototype.myCall = function(context = window){ //myCall函数的参数,没有传参默认是指向window
    context.fn = this //为对象添加方法(this指向调用myCall的函数)
    let args = [...arguments].slice(1) // 剩余的参数
    let res = context.fn(...args)  // 调用该方法,该方法this指向context
    delete context.fn //删除添加的方法
    return res
  }
  • apply
  Function.prototype.myApply = function(context = window){ //myCall函数的参数,没有传参默认是指向window
    context.fn = this //为对象添加方法(this指向调用myCall的函数)
    let res
    if(arguments[1]){ //判断是否有第二个参数
      res = context.fn(...arguments[1])// 调用该方法,该方法this指向context
    }else{
      res = context.fn()// 调用该方法,该方法this指向context
    }
    delete context.fn //删除添加的方法
    return res
  }
  • bind
Function.prototype.myBind = function(context = window){
  context.fn = this // 调用bind的函数
  let args = [...arguments].slice(1) // myBind的参数
  let bind = function(){
    let args1 = [...arguments].slice() // bind的参数
    return context.fn(args.concat(args1))
  }
return bind
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值