首先this是什么?

按照官方正规的解释,this关键字的意义被解释为“指向当前对象的引用”。this是面向对象语言中的一个重要概念,在JAVA,C++等面向对象的语言中,this固定指向运行时的当前对象。但是在JavaScript中,由于JavaScript的动态性(边解释边执行),this的指向在运行时才确定。它代表函数运行时自动生成的一个内部对象,一般在函数内部使用。

  1. this的值通常是由所在函数的执行环境决定,也就是说要看函数是如何被调用的;
  2. 同一个函数每一次调用,this都可能指向不同的对象;

为什么要改变this指向?

bind,call,apply的作用都是用来改变this指向的,那为什么要改变this指向呢?

var position="out";
let obj={position:"in",find:function(){console.log(this.position)}
};
obj.find(); //in,this指向obj对象
setTimeout(obj.find,0); //out,由于setTime()是异步操作,this指向window对象

如程序说展示 find()中的 this 是指向调用它的 obj 对象的,而在定时器 setTimeout 中调用 find(),this 是指向window对象的。但我们需要的是 find()的 this 指向obj对象,因此我们需要修改 this 的指向。

1.apply方法

apply接受两个参数,第一个是this的指向,第二个是函数接受的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,默认指向window(在浏览器中),使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。

eg:求数组中的最大值

var arr=[9,2,5,6];
console.log(Math.max.apply(null, arr)); //返回9

其中Math.max函数的参数是以参数列表,如:Math.max(9,2,5,6)的形式传入的,因此我们没法直接把数组当做参数,但是apply方法可以将数组参数转换成列表参数传入,从而直接求数组的最大值。

2.call方法

call方法的第一个参数也是this的指向,后面传入的是一个参数列表。当一个参数为null或undefined的时候,表示指向window,和apply一样,call也只是临时改变一次this指向,并立即执行。

var arr=[9,2,5,6];
console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3])); //返回9

采纳以参数列表的形式传入,而apply以参数数组的形式传入。

3.bind方法

bind方法和call很相似,第一参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数,调用新函数的时候才会执行目标函数。

面试题:

手写bind()函数

//实现bind方法Function.prototype.bind = function(oThis) {if (typeof this !== 'function') {// closest thing possible to the ECMAScript 5// internal IsCallable functionthrow new TypeError('Function.prototype.bind - what is trying to be bound is not callable');}var aArgs = Array.prototype.slice.call(arguments, 1),fToBind = this,fNOP = function() {},fBound = function() {// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用return fToBind.apply(this instanceof fBound? this: oThis,// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的aArgs.concat(Array.prototype.slice.call(arguments)));};// 维护原型关系if (this.prototype) {// 当执行Function.prototype.bind()时, this为Function.prototype // this.prototype(即Function.prototype.prototype)为undefinedfNOP.prototype = this.prototype; }// 下行的代码使fBound.prototype是fNOP的实例,因此// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例fBound.prototype = new fNOP();return fBound;};var arr=[1,11,5,8,12];var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3]);console.log(max(arr[4])); //12

为什么要改变this指向?相关推荐

  1. 【C 语言】指针数据类型 ( 不允许向 NULL 地址写入数据 | 不允许不断地改变指针指向 | 字面量存放位置 )

    文章目录 一.不允许向 NULL 地址写入数据 二.不允许不断地改变指针指向 三.字面量存放位置 一.不允许向 NULL 地址写入数据 声明指针变量 , 并为其 设置 NULL 初始值 , NULL ...

  2. java改变this指向_$.on()方法和addEventListener改变this指向

    jQuery $.on()方法和addEventListener改变this指向 标签(空格分隔): jQuery JavaScript jQuery $.on() jq的绑定事件使用$([selec ...

  3. 改变 this 指向的 call 和 apply

    一.call 方法 基本用法 function test() {console.log('hello world'); } test(); // hello world test.call(); // ...

  4. js 改变this指向的几种方法(个人学习笔记)

    1.call()和apply() 两中方法都能改变this指向,很类似,区别主要是第二个以后参数, call():第一个参数表示要把this指向的新目标,第二个之后的参数其实相当于传参,参数以,隔开  ...

  5. 浅析下关于js的 逗号运算符 和 改变this指向 的一道题(mv to git)

    为什么80%的码农都做不了架构师?>>>    刚刚登陆微博,想看下有什么八卦新闻,突然看到@JS小组 分享的一道题: @JS小组 是由资深前端工程师维护的一个小微博,既然由他们提出 ...

  6. this指向及改变this指向的方法

    原先总结过this指向问题,但看了大佬们写的之后,觉得自己遗漏了很多点,所以,结合大佬们的,重写一遍 一.函数的调用方式决定了 this 的指向不同: 1.普通函数调用,此时 this 指向 wind ...

  7. this指向和如何改变this指向 (详解)

    注:颜色标识为重要字眼.  目录:-this详解            -改变this指向的方法 一.this概述 它是JS的关键词,是一个代词"指代不明",需要代码执行过程中根据 ...

  8. JavaScript - this指向以及强行改变this指向

    this 指向 -官方:指当前代码执行的上下文环境(context) -私人: 就是一个使用在作用域内(全局 / 函数内)的关键字 全局作用域 this ->在全局作用域内,this就是wind ...

  9. 前端改变this指向的方法有哪些?如何判断this指向?

    bind.call.apply.箭头函数.new.这些都可以改变this指向,他们之间的区别是 1.call 和 apply 的this指向 call 和 apply其实是一样的,区别在于传参的时候参 ...

  10. 如何改变this指向?

    如何改变this指向? 在接触this指向问题,相信很多同学都面临this指向的问题,有些时候我们在对象方法内部使用this.而并不想让this指向当前本对象,这时候该怎么办呢?答案就是改变this指 ...

最新文章

  1. 20万Star的编程学习教程:让你的编码之路事半功倍!
  2. JAVA 正则表达式 分组
  3. 开源分布式平台-mooon系统结构
  4. 怎么学python知乎_你们都是怎么学 Python 的?
  5. 定理在数学中的简写形式_湘教版八年级数学上册知识点总结
  6. 关于 2020 年的前端趋势预测
  7. JZOJ 3426. 封印一击
  8. Java程序员须知的七个日志管理工具
  9. python生成词云教程(附带QQ聊天记录生成词云实战)
  10. 谷歌安装器 android8.0,Android 8.0版本安装谷歌四件套
  11. 反病毒工具-WinDBG
  12. 区块链十年一梦:有人辞官归故里,有人星夜来赶考
  13. 3090显卡 爆显存调试
  14. 我使用Hexo+Github搭建Blog的经验
  15. 什么是白金域名?白金域名为什么更贵?
  16. DB2数据库基本概念
  17. LEDE嵌入式无线路由系统定制
  18. GRASPIT安装流程
  19. 【杂货铺】中国房屋种类
  20. Excel学习——制作周报

热门文章

  1. 1.7 的ConcurrentHashMap要得不
  2. 在网页设计中如何排版,教你一些有效的方法,足够让你的排版变好看
  3. 【论文笔记】基于深度强化学习的机器人操作行为研究综述
  4. Linux 在centos下安装V Mware 出现vmware tools 选项框变成灰色的解决方法
  5. Python 判断日期为周几,是否工作日,法定假日
  6. 成功解决 cv2.error: OpenCV(4.6.0) D:\a\opencv-python以及Assertion“t>=0t<=n_classes“failed(训练PSPNet)
  7. l挡d挡切换_自动档汽车行驶中D档可直接换成L档么
  8. [BJDCTF 2nd]假猪套天下第一 -wp
  9. 2011年9月全国计算机等级考试四级网络工程师 试卷+题解
  10. 谁才是天朝最厉害的演员?让Python来为你揭晓!