概述

js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向。

apply()

apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。

var student = {
name : 'xiaoming'
}
function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
} getName.apply(student , ['MQ' , 'jj']); //MQ xiaoming jj

call()

call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。

var student = {
name : 'xiaoming'
}
function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
} getName.call(student , 'MQ' , 'jj'); //MQ xiaoming jj

apply(),call()常用方法

1.数组合并

var arr_1 = [1,2,3];
var arr_2 = [4,5,6];
[].push.apply(arr_1,arr_2);
console.log(arr_1) //[1,2,3,4,5,6]

2.获取数组中的最大值和最小值

var num_arr = [3,5,8,1,9];
var max_num = Math.max.apply(Math , num_arr);
var min_num = Math.min.call(Math , 3 , 5 , 8 , 1 , 9)
console.log(max_num) //9
console.log(min_num) //1

3.类(伪)数组使用数组方法

var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

bind()方法

bind()方法与call(),apply()类试,也可改变函数体内的this指向。

bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

var foo = {
bar : 1,
eventBind: function(){
var _this = this;
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(_this.bar); //1
});
}
}

使用bind解决保存this的问题

var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(this.bar); //1
}.bind(this));
}
}

 bind参数的使用:

var student = {
name : 'xiaoming'
} function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
} var getBindName = getName.bind(student,'lihui');
getName('Mrs','jj'); //Mrs jj
getBindName(); //lihui xiaoming undefined
getBindName('jj'); //lihui xiaoming jj
getBindName('Mrs','jj'); //lihui xiaoming Mrs
getName.call(student,'lihui') //lihui xiaoming undefined

 call 是把第二个及以后的参数作为 getName方法的实参传进去,而 getBindName方法的实参实则是在 bind 中参数的基础上再往后排。

apply、call、bind三者之间的比较

var student = {
age : 18
}
var studentInfo = {
getAge () {
return this.age
}
}
console.log(studentInfo.getAge.bind(student)()); //18
console.log(studentInfo.getAge.call(student)); //18
console.log(studentInfo.getAge.apply(student)); //18

 apply/call在改变函数上下文环境之后, 会立即执行函数。而bind()不会立即执行,而是返回一个改变了上下文 this 后的函数。

总结

  • apply 、 call 、bind 三者都是用来改变函数的this对象的指向
  • apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文
  • apply 、 call 、bind 三者都可以利用后续参数传参,只是方式不同
  • apply , call改变函数上下文之后会立即调用,而bind会返回一个改变了this的函数,以便以后调用

参考资料

1.【优雅代码】深入浅出 妙用javascript的call , apply , bind

2.javascript中的call , apply详解

  

深入理解js中的apply、call、bind的更多相关文章

  1. JS中的apply,call,bind深入理解

    在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...

  2. js 中call,apply,bind的区别

    call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...

  3. 图文结合深入理解 JS 中的 this 值

    图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...

  4. 如何理解js中的this和实际应用中需要避开哪些坑

    this是什么 this就是函数内部的关键字 看下面例子理解js中的this // 例子1 function fnOne () { console.log(this) } 'use strict' f ...

  5. 深入理解Js中的this

    深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...

  6. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  7. 深入理解JS中的对象(二):new 的工作原理

    目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...

  8. 深入理解JS中的对象(三):class 的工作原理

    目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...

  9. 如何更好的理解js中的this,分享2段有意思的代码

    关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...

随机推荐

  1. C#高级编程第9版 阅读笔记(一)

    一.前言 C# 简洁.类型安全的面向对象的语言. .NET是一种在windows平台上编程的架构——一种API. C#是一种从头开始设计的用于.NET的语言,他可以利用.NET Framework及其 ...

  2. Java爬虫

    作为一位Java爬虫的初学者,分享一下自己的心得.所用到的jar包 org.codehaus.jettison.jar jsoup-1.7.3.jar个人认为爬虫的实现机制:获取Docume对象-&g ...

  3. Ubuntu 16.04 LTS 下安装MATLAB2015b 以及Matlab system error解决办法

    下载MATLAB2015b破解版 操作系统:Ubuntu 16.o4 LTS 程序文件:Matlab2015b-glnxa64破解版 解压提取文件:在ubuntu系统下可以直接提取压缩文件,得到三个文 ...

  4. uva12716 GCD XOR

    个人博客:http://acbingo.cn/2015/06/04/uva12716/ 被紫薯上*和素数筛法类似*这句话给误解了= =,一直以为存在某种关系,在枚举c或者a时,可以根据当前的答案,筛掉 ...

  5. redis3.2新功能--GEO地理位置命令介绍

    概述 redis3.2发布rc版本已经有一段时间了,估计RedisConf 2016左右,3.2版本就能release了.3.2版本中增加的最大功能就是对GEO(地理位置)的支持.说起redis的GE ...

  6. [译]ASP.NET Core 2.0 带初始参数的中间件

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...

  7. PHP获取文件扩展名的五种方式

    这是我应聘实习时遇到的一道笔试题: 使用五种以上方式获取一个文件的扩展名. 要求:dir/upload.image.jpg,找出 .jpg 或者 jpg , 必须使用PHP自带的处理函数进行处理,方法 ...

  8. Redis主从环境配置

    1.Redis主从同步原理 redis主服务器会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,然后将数据文件同步给从服务器,从服务器加载记录文件,在内存库中更新新数据. 2.VMWar ...

  9. 微信小程序之页面下拉刷新

    如果需要给单个页面设置下拉刷新功能,不需要写在""window"对象里面,直接在  文件名称.json 里面设置即可 { "enablePullDownRefr ...

  10. Windows环境下多线程编程原理与应用读书笔记(2)————面向对象技术

    面向对象技术是学C++需要重点掌握的知识,因为我觉得自己的基础还是比较可以,这一章节的内容就只是粗略的读了一遍,在此就不做过多的笔记.