我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何改变函数的this指向

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何改变函数的this指向

本篇内容介绍了“如何改变函数的this指向”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

如果是函数声明,那么函数内部的this指向全局对象或者调用该函数的对象。

箭头函数的this绑定的是父级作用域内的this

使用call,apply,bind可以绑定this指向。其中bind是永久改变this指向并且不会立即执行。apply,call临时改变this指向并且立即执行。

apply,call不同之处在于调用的参数形式:

call(thisArg, arg1?, arg2?, arg3?…)第一个参数代表this指向,剩下的参数就是原函数的参数。

apply(thisArg, argArray?)第一个参数代表this指向,第二个参数是以数组的形式传递参数。

var obj = {

x: 'obj',

getX: function() {

// 注意这里不能使用箭头函数

return this.x;

}

};

// 调用 obj 对象上的函数属性, this就会绑定为obj

// 'obj'

console.log(obj.getX());

var x = 'window';

function target(a, b, c) {

console.log(a, b, c);

return this.x;

}

// undefined undefined undefined

// 'window'

console.log(target());

const targetBound = target.bind(obj, 1); // 此时targetBound就是一个改变了this指向的target

// 1 2 3

// 'obj'

console.log(targetBound(2, 3));

// 4 5 6

// 'obj'

console.log(target.call(obj, 4, 5, 6));

// 7 8 9

// 'obj'

console.log(target.apply(obj, [7, 8, 9]));

自定义实现call,apply,bind

这三个函数都有很强的错误处理功能,假如传入的thisArg是一个基本类型,也会被使用包装类替换,虽然不会报错,但是不推荐这样写,尽量传递复杂类型的变量作为thisArg。

自定义实现myBind,myCall,myApply

// 先定义一个函数将任意类型都转换成对象,用于指向this

function anyToObj(value) {

  // symbol, bigint 就不判断了,直接在default中

  switch (typeof value) {

    case 'boolean':

      return new Boolean(value);

    case 'number':

      return new Number(value);

    case 'string':

      return new String(value);

    case 'undefined':

      return this;

    case 'object':

      if (value === null) return this; // 这里的this就指向了全局对象

      return value;

    default:

      return value;

  }

}

Function.prototype.myBind = function (thisArg, …argArray) {

  // 防止出现 const myBind = Function.prototype.myBind; myBind();

  if (typeof this !== 'function') {

    throw new TypeError('myBind must be called on a function');

  }

  const that = this; // this 就指向 f.myBind() 的 f

  const thatArg = anyToObj(thisArg); // 处理一下thisArg

  const myBound = function (…args) {

    // 指定唯一的键

    const tempKey = Symbol('__innerFunction__');

    thatArg.tempKey = that; // 将 that 函数赋值给一个对象的属性

    let ret;

    if (this instanceof myBound) {

      // 调用 myBind 之后返回的是 myBound,假如调用 new myBound(),就会进这个分支

      ret = new thatArg.tempKey(…argArray.concat(args));

    } else {

      // 这里是调用 myBound(),这样调用 tempKey 方法里的 this 就指向了 thatArg

      ret = thatArg.tempKey(…argArray.concat(args));

    }

    // 不会对对象造成污染

    delete thatArg.tempKey;

    return ret;

  };

  return myBound;

};

// 与 myBind 相比直接调用了

Function.prototype.myCall = function (thisArg, …argArray) {

  if (typeof this !== 'function') {

    throw new TypeError('myCall must be called on a function');

  }

  const thatArg = anyToObj(thisArg);

  const tempKey = Symbol('__innerFunction__');

  thatArg.tempKey = this;

  const ret = thatArg.tempKey(…argArray);

  delete thatArg.tempKey;

  return ret;

};

// 与 myCall 相比,第二个参数希望是数组形式,多了个 CreateListFromArrayLike 用于转化 argArray

Function.prototype.myApply = function (thisArg, argArray) {

  if (typeof this !== 'function') {

    throw new TypeError('myApply must be called on a function');

  }

  const CreateListFromArrayLike = function (val) {

    // 同样缺乏 bigint 的处理,直接放在 default 中

    switch (typeof val) {

      case 'string':

      case 'number':

      case 'boolean':

      case 'symbol':

        throw new TypeError('CreateListFromArrayLike called on non-object');

      case 'object':

        if (Array.isArray(val)) return val;

        if (val === null) return [];

        return Array.from(val);

      default:

        return [];

    }

  };

  // 检测 argArray 的类型

  const tempArgArray = CreateListFromArrayLike(argArray);

  const thatArg = anyToObj(thisArg);

  const tempKey = Symbol('__innerFunction__');

  thatArg.tempKey = this;

  const ret = thatArg.tempKey(…tempArgArray);

  delete thatArg.tempKey;

  return ret;

};

// 这样 myBind,myCall,myApply就完成了,下面进行测试

var obj = {

x: 'obj',

getX: function(a, b, c) {

console.log(a, b, c);

return this.x;

}

}

var x = 'window';

// 1 2 3

// 'obj'

console.log(obj.getX(1, 2, 3));

// target变成一个全局函数,this 指向全局对象

const target = obj.getX;

// 1 2 3

// 'window'

console.log(target(1, 2, 3));

const targetBound = target.myBind(obj, 1);

// 1 2 3

// 'obj'

console.log(targetBound(2, 3));

// 4 5 6

// 'obj'

console.log(target.myCall(obj, 4, 5, 6));

// 7 8 9

// 'obj'

console.log(target.myApply(obj, [7, 8, 9]));

“如何改变函数的this指向”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何改变函数的this指向

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript进阶学习之初识类、函数进阶、如何改变this指向

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了类、函数进阶以及如何改变this指向的相关内容,希望对大家有帮助。
2022-11-22

如何理解JavaScript函数this指向问题

这篇文章给大家介绍如何理解JavaScript函数this指向问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、 函数内 this 的指向这些 this的指向,是当调用函数的时候确定的。 调用方式的不同决定了thi
2023-06-21

JS箭头函数的this指向分析

本篇内容介绍了“JS箭头函数的this指向分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!箭头函数是ES6中的新增特性,他没有自己的thi
2023-06-25

javascript函数的4种调用方式与this的指向

本文主要介绍了javascript函数的4种调用方式与this(上下文)的指向,文中有详细的代码示例,感兴趣的同学可以参考阅读一下
2023-05-19

Vue如何用this.$set改变数组里的某个值

这篇文章主要介绍了Vue用this.$set改变数组里的某个值,文中通过示例代码介绍了vue中this.$set()的用法----更新数组和对象的值,需要的朋友可以参考下
2022-12-19

JavaScript如何改变函数作用域

本篇内容介绍了“JavaScript如何改变函数作用域”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!使用call和apply方法call和a
2023-07-05

php数组中改变指针位置的函数介绍

这篇文章主要介绍“php数组中改变指针位置的函数介绍”,在日常操作中,相信很多人在php数组中改变指针位置的函数介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php数组中改变指针位置的函数介绍”的疑惑有所
2023-06-20

如何用JavaScript编写改变颜色函数

JavaScript编写改变颜色函数JavaScript是一种广泛应用于Web开发的编程语言。它可以让网页变得更具交互性和动态性。在JavaScript中,改变元素颜色是一项非常基础的操作,因为颜色可以传达信息,美化用户界面,但同时又非常简单。本文将介绍如何使用JavaScript编写改变颜色函数。一、使用JavaScript改变元素颜色要改变元素颜色,JavaScript需要
2023-05-14

编程热搜

目录