JavaScript this和bind、apply、call

  • this指向函数执行时的当前对象,它会随着执行环境的改变而改变。
  • this 是保留关键字,无法被修改
  • 任何函数本质上都是通过某个对象来调用的
  • 所有函数内部都有一个变量this,他的值是调用函数的当前对象

this指向

  • 在事件中,this 表示接收事件的HTML元素。
  • 普通函数中:谁调用了函数或者方法,那么这个函数或者对象中的this就指向谁
    • **fn()**为全局对象,在浏览器中是window,严格模式下为undefined
    • **p.fn()**:p,指向对象
    • **new fn()**:新创建的对象
    • **p.call(obj)**:obj
    • bind、call、apply 方法可以将 this 引用到任何对象。
  • 匿名函数:指向**window,**匿名函数的执行具有全局性
  • 箭头函数
    • 箭头函数中的this是在函数定义的时候就确定下来的,而不是在函数调用的时候确定的;
    • 箭头函数中的this指向恒定为父级作用域的执行上下文(父级作用域的this)
    • 箭头函数无法使用bind、call、apply方法改变this指向,因为其this值在函数定义的时候就被确定下来。

修改this指向函数

bind

  • 不会调用函数,但是可以改变函数内部this指向
  • 返回 由指定this 和指定实参的原函数拷贝,返回值中this永久改变
  • 使用addeventlinstener和attachevent解决不同版本的浏览器的适配问题
  • 修改attachevent内的回调函数使其this指向obj,与addeventlinstener默认的this指向obj统一

call、apply

  • 都是函数的方法,需要通过函数对象调用,函数也会执行
  • 调用call和apply会将第一个对象指定为第一个参数 ,此时这个对象会成为函数执行时this
  • call方法可以将实参在对象之后一次传递
  • apply需要将实参封装到一个数组中统一传递
  • call 和apply 都是用来改变函数的this的,改变向的this为第一个参数,原先传入的参数从第二位开始
  • 以函数形式调用时,this永远都是window
  • 以方法的形式调用时,this是调用方法的对象
  • 以构造函数的形式调用时,thi s是新创建的那个对象
  • 使用call和apply调用时,this是指定的那个对象
fun.call(this)//等同于 fun()
fun.call(obj)//此时指向obj
/* sayname内为一个返回此时this的函数,返回值为obj 
即 call改变了fun.sayname的this 
可以理解为一个修改当前语句this的方法 */
fun.sayname.call(obj)
fun.call(obj,a,b)//a,b类似其他函数传入的实参 即从第二位开始
fun.apply(obj,[a,b])//封装
// 给 Father 增加 name 和 age 属性
function Father(myName, myAge) {
    this.name = myName;
    this.age = myAge;
}

function Son(myName, myAge) {
    // 通过这一步,将 father 里面的 this 修改为 Son 里面的 this;另外,给 Son 加上相应的参数,让 Son 自动拥有 Father 里的属性。最终实现继承
    //相当于在son身上调用了father方法
		Father.call(this, myName, myAge);
}

const son1 = new Son('千古壹号', 28);
console.log(JSON.stringify(son1));

上方代码中,通过 call() 方法,让 Son 继承了 Father 里面的 name 和 age 属性。
打印结果:
{"myName":"千古壹号","myAge":28}
const arr1 = [3, 7, 10, 8];

// 下面这一行代码的目的,无需改变 this 指向,所以:第一个参数填 null,或者填 Math,或者填 this 都可以。严格模式中,不让填null。
const maxValue = Math.max.apply(Math, arr1); // 求数组 arr1 中元素的最大值
console.log(maxValue);

const minValue = Math.min.apply(Math, arr1); // 求数组 arr1 中元素的最小值
console.log(minValue);

call appy bind的相同和不同

  • 相同:都可以改变函数内部的this指向。
  • 区别点:
    • call 和 apply 会调用函数,并且改变函数内部this指向。
    • call 和 apply 传递的参数不一样,call 传递参数arg1,arg2…形式, apply 必须数组形式
    • bind 不会调用函数,可以改变函数内部this指向。
    • 主要应用场景:
      • call 经常做继承。
      • apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
      • bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值