博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript 中经典的call 、apply、bind方法以及this指向详解
阅读量:6549 次
发布时间:2019-06-24

本文共 2758 字,大约阅读时间需要 9 分钟。

前言

一说到js中的call、apply、bind方法,就一定会和this联系起来,百分之九十以上的问题都是有关这三个函数方法中this的指向问题,在前端面试题中非常的常见,掌握了这三个方法的this指向问题,不仅可以在面试官前侃侃而谈,加深面试官对你的印象,而且可以提高我们js代码的编码水平和编码水平,作为一个前端这是我们必须掌握的基本知识。 再说他们三个之前,我们先来说下this吧,懂了this的指向问题,也就掌握了这三个方法的精髓。

this

this是函数内部的一个特殊的对象,,this引用的是函数据以执行的环境对象——或者也可以说是this值(当在网页的全局作用域调用函数时,this 对象引用的就是 window )。简单的说this指向调用该函数的环境对象。再简单一点就是谁调用它就指向谁,下面具体的说说this的调用指向

1.纯函数调用

var x = 1;function test() {   console.log(this.x);}test();  // 1  this指向全局对象复制代码

2.作为对象的方法调用

var obj = {        n:'1',    m:function test() {  console.log(this.n);}         };obj.m()//1 this指向obj复制代码

3.作为构造函数调用

var x = 2;function Test() { this.x = 1;}var obj = new Test();obj.x // 1 this 指向objx=2 //说明this并不是指向的是window复制代码

4.事件绑定中的this

备注:下面的两个this指向参考了这个作者的文章,在通读之后觉得写的很透彻明了,就直接节选了部分,自己也就不在罗嗦了。

链接:

事件绑定共有三种方式:行内绑定、动态绑定、事件监听;行内绑定的两种情况:

复制代码

行内绑定事件的语法是在html节点内,以节点属性的方式绑定,属性名是事件名称前面加'on',属性的值则是一段可执行的 JS 代码段;而属性值最常见的就是一个函数调用;当事件触发时,属性值就会作为JS代码被执行,当前运行环境下没有clickFun函数,因此浏览器就需要跳出当前运行环境,在整个环境中寻找一个叫clickFun的函数并执行这个函数,所以函数内部的this就指向了全局对象window;如果不是一个函数调用,直接在当前节点对象环境下使用this,那么显然this就会指向当前节点对象;动态绑定与事件监听:

复制代码

因为动态绑定的事件本就是为节点对象的属性(事件名称前面加'on')重新赋值为一个匿名函数,因此函数在执行时就是在节点对象的环境下,this自然就指向了本节点对象;

5.window定时器的this

var obj = {    fun:function(){        this ;    }}setInterval(obj.fun,1000);      // this指向window对象setInterval('obj.fun()',1000);  // this指向obj对象复制代码

setInterval() 是window对象下内置的一个方法,接受两个参数,第一个参数允许是一个函数或者是一段可执行的 JS 代码,第二个参数则是执行前面函数或者代码的时间间隔;

在上面的代码中,setInterval(obj.fun,1000) 的第一个参数是obj对象的fun ,因为 JS 中函数可以被当做值来做引用传递,实际就是将这个函数的地址当做参数传递给了 setInterval 方法,换句话说就是setInterval 的第一参数接受了一个函数,那么此时1000毫秒后,函数的运行就已经是在window对象下了,也就是函数的调用者已经变成了window对象,所以其中的this则指向的全局window对象;

而在 setInterval('obj.fun()',1000) 中的第一个参数,实际则是传入的一段可执行的 JS 代码;1000毫秒后当 JS 引擎来执行这段代码时,则是通过 obj 对象来找到 fun 函数并调用执行,那么函数的运行环境依然在 对象 obj 内,所以函数内部的this也就指向了 obj 对象;

6.apply、call调用

apply方法和call方法都是函数非继承而来的方法,这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值。apply() 方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是 Array 的实例,也可以是arguments对象。

call()方法与apply()方法的作用相同,区别是第二个传递给函数的参数必须是一一列举出来。(对于this的指向问题,只要记住一点,this值指向该方法的第一个参数就可以了,语法就这样规定)

var x = 0;function test() { console.log(this.x);}var obj = {};obj.x = 1;test.apply(obj,[0])//this指向obj复制代码
var x = 0;function test() { console.log(this.x);}var obj = {};obj.x = 1;test.call(obj,0,1,2)//this指向obj 复制代码

7.bind调用

这个方法会创建一个函数的实例,其 this 值会被绑定到传给 bind() 函数的值。也就是他会返回一个函数。

window.color = "red";var o = { color: "blue" };function test(){alert(this.color);}var obj = test.bind(o);//this指向oobj(); //blue复制代码

apply、call、bind 的区别

apply、call的作用一样,只是第二个参数传递方式不同,apply要求是数组形式,call要求是将参数一一列举出来, apply和call都是改变this的指向后就执行函数,而bind是改变this指向后返回一个函数,您得手动再执行这个函数

结尾

本文参考阮一峰的this指向文章,以及通读了数篇关于this指向的问题,形成自己的理解,对于有关摘录部分也做了原文链接说明,如有纰漏,欢迎指正。

转载于:https://juejin.im/post/5cb1ef0b6fb9a068646c098f

你可能感兴趣的文章
我的友情链接
查看>>
KVM组件bug报告方法
查看>>
HTML5初学---坦克大战基础
查看>>
Solr增量更新索引
查看>>
抵制克苏恩[Lydsy2017年4月月赛]
查看>>
MySql Study Notes
查看>>
6 - laravel 基础 - 视图与模板引擎
查看>>
团队第二次作业
查看>>
linux 查询当前文件夹下的目录数量
查看>>
【python】入门第一篇
查看>>
1682: [Usaco2005 Mar]Out of Hay 干草危机
查看>>
supersr--NSURLConnection iOS2.0苹果原生请求
查看>>
iphone-common-codes-ccteam源代码 CCPlistFileReader.h
查看>>
构造方法
查看>>
SQL效率之索引
查看>>
线性支持向量分类机及其实现
查看>>
Yslow
查看>>
Axure产品原型设计工具
查看>>
ASM文件系统
查看>>
ajax学习笔记(原生js的ajax)
查看>>