写点什么

如何优雅的改变 this 指向

作者:bo
  • 2022 年 7 月 22 日
  • 本文字数:1734 字

    阅读完需:约 6 分钟

前言

Javascript 为我们专门提供了一些函数方法来帮我们更优雅的处理函数内部 this 的指向问题,常用的有bind() call() apply()

this 指向

this 的指向,是我们调用函数的之后确定的。调用方式的不同决定了 this 的指向不同,一般指向我们的调用者。

改变 this 的三个函数

call()

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

语法

fun.call(thisArg, arg1, arg2, ...)
复制代码
  • thisArg:在 fun 函数运行时指定的 this 值

  • args1, arg2, ... :传递的其它参数

  • 返回值就是函数的返回值,因为它就是调用函数

var ldh = {    name: '刘德华'}function f(a, b) {    console.log(this);		//ldh    console.log(a + b);		//5}f.call(ldh, 2, 3);
复制代码

作用

  • call 第一个可以调用函数 第二个可以改变函数内的 this 指向

  • call 的主要作用是可以实现继承

function Father(uname, age, sex) {  this.uname = uname;  this.age = age;  this.sex = sex;}
function Son(uname, age, sex) { Father.call(this, uname, age, sex);}var son = new Son('刘德华', 22, '男');console.log(son);// { uname: '刘德华', age: 22, sex: '男' }
复制代码


Father.call(this, uname, age, sex); 在调用父构造函数的同时,将父构造函数中的 this 指向子构造函数中的 this,这样子构造函数就可以使用父构造函数中的 uname,age,sex 了

apply()

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

语法

fun.apply(thisArg, [argsArray])
复制代码
  • thisArg:在 fun 函数运行时指定的 this 值

  • argsArray:传递的值,必须包含在数组里面

  • 返回值就是函数的返回值,因为它就是调用函数

var ldh = {    name: '刘德华'}
function f(arr) { console.log(this); //ldh console.log(arr); //小红}f.apply(ldh, ['小红']);
复制代码

作用

  • 也是调用函数 第二个可以改变函数内部的 this 指向

  • 但是它的参数必须是数组(伪数组)

  • apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求最大值 Math.max()

var arr = [1, 5, 66, 44, 8];var max = Math.max.apply(Math, arr);console.log(max);	//66
// console.log(Math.max(...arr)); // 这种也可以,我们这里就是练习一下apply的用法
复制代码

bind()

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

语法

fun.bind(thisArg, arg1, arg2, ...)
复制代码
  • thisArg:在 fun 函数运行时指定的 this 值

  • args1, arg2, ... :传递的其它参数

  • bind 方法不会调用函数,但是能改变函数内部的 this 指向

  • 返回值是 fun 改造完的原函数拷贝(产生了新的函数)

var ldh = {    name: '刘德华'}
function f(a, b) { console.log(this); //ldh console.log(a + b); //5}var fn = f.bind(ldh, 2, 3);fn();
复制代码

作用

  • 不会调用原来的函数

  • 可以改变函数内部的 this 指向

  • 返回的是原函数改变 this 之后产生的新函数

  • 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的 this 指向,这个时候用 bind

定时器

有一个按钮,当我们点击了之后,就禁用这个按钮,3 秒之后开启这个按钮

<button>点击</button>
复制代码


var btn = document.querySelector('button');btn.onclick = function() {    this.disabled = true;    var that = this;    setTimeout(function() {        that.disabled = false;    }, 3000)}
复制代码

我们之前会通过 var that = this; 保留 this 的指向,在学完 bind 方法后,可以用 bind 来保留 this 指向

var btn = document.querySelector('button');btn.onclick = function() {    this.disabled = true;    setTimeout(function() {        this.disabled = false;    }.bind(this), 3000)}
复制代码

总结

call apply bind 总结

相同点

都可以改变函数内部的 this 指向

不同点

  1. call 和 apply 会带哦用函数,并且改变函数内部 this 指向

  2. call 和 apply 传递的参数不一样 call:arg1, arg2, ...apply:[arg] 数组形式

  3. bind 不会调用函数,可以改变函数内部 this 指向

主要应用场景

  1. call 经常做继承

  2. apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值

  3. bind 不调用函数,但是还想改变 this 指向,比如改变定时器内部的 this 指向

最后

肝!肝!肝!我们一起加油~~~

发布于: 4 小时前阅读数: 11
用户头像

bo

关注

还未添加个人签名 2022.07.11 加入

还未添加个人简介

评论

发布
暂无评论
如何优雅的改变this指向_JavaScript_bo_InfoQ写作社区