JavaScript中的bind,call和apply函数的用法和区别
一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下
首先要理解的第一个概念,JavaScript中函数调用的方式,总结下来,有以下4种
1. 方法调用
2. 正常函数调用
3. 构造器函数调用
4. apply/call 调用
要明白的第2个概念, JavaScript 中的函数,无论是上面哪种函数调用方式,除了你函数声明时定义的形参外,还会自动给函数添加两个形参,分别是this 和 arguments
要明白的第3个概念, Javascript中的函数,存在函数上下文(context) 这么一个概念, 而函数上下文又存在【定义时上下文】,【运行时上下文】,【上下文是可以改变的】这样子的情况, 而第2个概念中的this, 指向的就是当前函数中的上下文
要明白的第4个概念, 也是我们今天在这里要讲的call, apply函数的目的 => 它们在JavaScript函数中存在的目的,就是为了改变某个函数运行时的上下文(context)而存在的, 换句话说,是为了改变函数体内部this的指向
现在我们一个一个来看
1. 方法调用函数的方式
应该可以理解,所谓方法调用函数的方式,就是说把一个函数定义为一个对象的方法,然后通过调用这个对象的该方法,来达到调用该函数的目的
直接上代码
var myValue = { para: 5,
setFunc: function(xvalue){ this.para = xvalue; }
} myValue.setFunc(0);
在这里,函数setFunc作为变量myValue的也给方法存在,所以使用myValue.setFunc()的形式就可以调用它。在这里,函数setFunc中的this,绑定的上下文就是myValue, 所以this.para取到的就是对象myValue的para属性
2. 正常函数调用
function setValue(xvalue)
{
this.para = xvalue;
} setValue(5);
上面,我们正常的定义了一个函数setValue,然后正常的调用setValue(5). 在这里,函数setValue里面的this绑定的是全局对象. 如果这段JavaScript代码是运行在浏览器中,那么这里的this指向的就是浏览器的全局对象window. 所以这里this.para 等价于 window.para. 那有人肯定会很奇怪,如果当前浏览器的window中不存在para属性呢,那么这个时候,在这里,javascript会自动给全局对象window加上para属性,同时在这里赋值为5
3. 构造器函数调用
JavaScript 中的构造函数,大家知道,首先作为构造函数的函数名首字母需要大写,在函数内部必须有this关键字。 我们来看一下构造函数的调用
function SetValue(xvalue)
{
this.para = xvalue;
} var myFunc = new SetValue(5);
在这里,SetValue函数不是一个普通函数,它是一个构造函数, 调用它是使用new 关键字来生成一个新的对象myFunc, 在这里,this绑定的上下文就不再是window对象了,而是新的对象myFunc
所以 console.log(myFunc.para) // 输出5
4. apply/call 来调用函数
我们可以看到,上面三种函数调用方式,this指向都不一样,但是我们程序员都无法自定义或者说更改this的绑定指向。 那么,如果我们需要在程序中自己指定this的绑定上下文,有没用方法呢。这就是apply/call的用处了
JavaScript 中所有函数都有一个公共的prototype => Function, 而Function 这个原型自带了不少的属性和方法,其中就有apply, call, bind方法。 我们首先来看看apply 和 call方法
apply => 当一个对象没有某个方法时,但这个方法在其他地方存在。可能使用这个方法的apply方法,把这个方法运用到这个对象上。 它有两个参数 apply(thisObj, [arg1,arg2,arg3...])
第1个参数是传递给这个函数用来绑定this的值(指定这里this所绑定的上下文是哪一个)
第2个参数是一个数组
我们直接上代码,来看一个例子
function setValue(xvalue)
{
this.para = xvalue;
} var applyObj = {}; setValue.apply(applyObj,[10]); alert(setValue.para); // undefined
alert(applyObj.para); //
可以看到,刚开始对象applyObj是我们定义的一个空对象,然后通过函数原型默认持有的apply方法,我们把函数setValue通过apply方法应用到空对象applyObj上去,使得对象applyObj拥有了setValue方法,同时,通过第一个参数,指定this所绑定的当前上下文是applyObj对象,传入的参数为10
call 方法和apply方法几乎没有区别,唯一的区别是, 它的第二个参数不是以数组的形式,而是通过逗号来列出参数的形式 call(thisObj,arg1,arg2,arg3...) 我们直接来看代码
function addValue(xvalue, yvalue)
{
this.para = xvalue + yvalue;
} var applyObj = {}; addValue.call(applyObj,2,3); alert(addValue.para); // undefined
alert(applyObj.para); //
当然, 如果在call 或者apply方法中,你传入的第一个参数是null, 那么在这种情况下,函数中的this 指向的依然会是全局对象window
然后,我们来看一看bind
bind的功能和上面一样,它接受的参数和call一样. 唯一的区别是,函数使用bind方法后会生成一个新的函数,你想什么时候调用新的函数,就什么时候调用. 我们来看一个例子
var myObj = {
"x" : 4
};
function addValue(y) {
alert(this.x + y);
}
addValue.apply(myObj, [5]);
addValue.call(myObj, 5);
var foo1 = addValue.bind(myObj, 5);
foo1();
最新文章
- Format 函数示例
- HTML5模仿逼真地球自转
- [php-src]理解Php内核中的函数与INI
- Linux下的split 命令(将一个大文件根据行数平均分成若干个小文件)
- 三星Galaxy S4(GT-I9500)获取ROOT权限教程(转)
- 【转】如何下载并编译Android4.0内核源码goldfish(图文)
- php每秒输出一次
- JAVA文件的两种读取方法和三种写入方法
- 用 pdf.js兼容部分安卓显示PDF在线预览 时,a标签直接链接参数文件不能含中文的解决办法
- jenkins 启动被杀死
- spark DAG 笔记
- python 数字以及字符串(方法总结,有的可能理解错误)
- Android数据存储:File
- “failed to excute script xxx” PyInstaller 打包python程序为exe文件过程错误
- 【AtCoder】CADDi 2018
- Endianess(字节次序)简介
- ES6 Javascript 实用开发技巧
- 算法笔记_028:字符串转换成整数(Java)
- 2016-2017 National Taiwan University World Final Team Selection Contest C - Crazy Dreamoon
- java的接口为什么不能实例化
热门文章
- centos6下yum安装mariadb数据库的解决方法
- C# .NET 微信开发-------当微信服务器推送消息时如何接收处理
- CSS基础学习-4.CSS属性_背景、颜色、边框
- iptables防火墙入门
- css3小动画:鼠标hover后text-decoration的动画
- ACID理解
- MySQL 关于视图的操作
- Oracle之:Function :numberToDate()
- HDU 6050 - Funny Function | 2017 Multi-University Training Contest 2
- java——ThreadLocal、ThreadLocalMap、Thread三者的关系