JavaScript中的call()、apply()与bind():
关于call()与apply():
在JavaScript中,每个函数都有call与apply(),这两个函数都是用来改变函数体内this的指向,并调用相关的参数。
看一个例子:
定义一个animal对象,该对象有一个jump()方法:

var animal = {
type:'animal',
jump:function(name){
return this.type + ' is ' + name;
}
}
some_animal.jump('dog');
**"animal is dog"**

如果这个时候有一个对象other_animal对象,只有一个type属性:
var other_animal = {
type:'other animal'
}
这种情况下也要调用animal的jump()方法,这时候就可以用到jump()函数中的call()。
one_animal.jump.call(other_animal,'cat'). **"other animal is cat"**
当jump被调用时,其中的this被设置成为了other_animal对象的引用,所以this.type返回的是other animal。
当有多个参数的时候,
one_animal.method.call(other_animal,'cat','mouse').
apply()与call()基本相同,唯一的不同是参数的传递形式。
apply()传递的是一个数组。
如下两行是等效的:
one_animal.method.call(other_animal,'cat','mouse'). one_animal.method.call(other_animal,['cat','mouse']).
分享一道题目:
定义一个 log 方法,让它可以代理 console.log 方法。
常见解决方案:

function log(msg) {
console.log(msg);
}
log(1); //1
log(1,2); //1

当传入参数不确定时,上述方法就失效了。便可考虑用apply()或call(),这里参数个数不确定,用apply()更好。

function log(){
console.log.apply(console, arguments);
};
log(1); //1
log(1,2); //1 2

关于bind():
bind()的用法跟call()与apply()的用法很相似,都是改变函数体内this的指向。
MDN的解释是:bind()方法会创建一个新函数。当这个新函数被调用时,bind()的第一个参数将作为它运行时的 this, 之后的一序列参数将会在传递的实参前传入作为它的参数。

this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

在常见的单体模式中,通常会使用_this,that,self等来保存this,为了在改变了上下文环境之后能够继续使用它们。

var func = {
num:1,
event:function(){
var that = this;
$('.class').click(function(){
console.log(that,num);
})
}
}
//用bind()来改变this:
var func = {
num:1,
event:function(){
$('.class').click(function(){
console.log(this,num);
}.bind(this))
}
}

在这里,click被调用时,this被设置成传入的值。当回调函数执行时,this便指向func对象。

more example:
var method = function(){
console.log(this.x);
}
method();//undefined
var method_func = method.bind(func);
method_func();

注意:
在JavaScript中多次使用bind()是无效的。
原因是,bind()的实现,相当于在使用函数内部包了一个call/apply,第二次bind()相当于再包住一次bind(),所以无效。
比较apply、call、bind:

var method = {
x: 3,
};
var func= {
getX: function() {
return this.x;
}
}
console.log(func.getX.bind(method)()); //3
console.log(func.getX.call(method)); //3
console.log(func.getX.apply(method)); //3

JavaScript中的call()、apply()与bind():的更多相关文章
- Javascript中call,apply,bind方法的详解与总结
在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...
- Javascript中call、apply、bind函数
javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...
- Javascript中call,apply,bind的区别
一.探索call方法原理 Function.prototype.call = function(obj) { // 1.让fn中的this指向obj // eval(this.toString().r ...
- JavaScript 中call()、 apply()、 bind()改变this指向理解
最近开发的过程中遇到了this指向问题,首先想到的是call().apply().bind()三个方法,有些时候这三个方法确实是十分重要,现在我们就把他们的使用方法及异同点讲解一下. 1.每个函数都包 ...
- JavaScript中call、apply、bind、slice的使用
1.参考资料 http://www.cnblogs.com/coco1s/p/4833199.html 2.归结如下 apply . call .bind 三者都是用来改变函数的this对象的指向 ...
- javascript中call()、apply()、bind()的用法终于理解
其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例1 obj.objAge; //17 obj.myFun() //小张年龄undefined 例2 shows( ...
- (转)javascript中call()、apply()、bind()的用法
其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例1 obj.objAge; //17 obj.myFun() //小张年龄undefined 例2 shows( ...
- javascript中call、apply、bind详解
1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定 ...
- JavaScript 中 call,apply 和 bind
call and apply 改变函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数. function test() {} test() == test.ca ...
- javascript中call()、apply()、bind()的用法理解
一.bind的用法 第一个:obj.showInfo('arg','arg_18');中传的2个参数通过showInfo方法改变的是obj下中的name和age 第二个:obj.showInfo.bi ...
随机推荐
- eclipse在多modules项目结构下避免模块间依赖引用的场景
这个在单一classLoader时,不会有问题.如果多classloader下会有问题. 假设工程有两个模块,module2 依赖module1 当我们执行mvc eclipse:eclipse后,然 ...
- touchmover手机移动端的拖动
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta name= ...
- grep[行号&正则匹配字符有颜色]
事情是这样的,昨天在深入学习grep命令时,看到别人博客用grep正则匹配,不仅行数有颜色,而且匹配到的字符也有颜色.我在CRT也试了下,毛颜色都没有.顿时感觉 so low. 解决 编辑vim~/. ...
- C#调用TSC条码打印机打印条码
#region 调用TSC打印机打印条码 /// <summary> /// 调用TSC打印机打印条码 /// </summary> /// <param name=&q ...
- php imagemagick 处理 图片剪切、压缩、合并、插入文本、背景色透明
php有一款插件叫做imagemagick,功能很强大,提供了图片的很多操作,图片剪切.压缩.合并.插入文本.背景色透明等.并且有api方法调用和命令行操作两种方式,如果只是简单处理的话建议api方法 ...
- C#开发移动应用系列(4.调用系统应用,以及第三方应用(调用与被调用))
前言 上篇文章地址: C#开发移动应用系列(1.环境搭建) C#开发移动应用系列(2.使用WebView搭建WebApp应用) C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知识) 写完这篇 ...
- MVC通过递归+部分视图实现评论
前一个项目里有一个关于评论系统的需求.感觉这个评论的实现还是蛮好玩的,所以记录下这个系统的实现相关内容. 功能需求: 1.用户可以再视屏下方留言. 2.用户可以再别的用户留言下方回复. 3.用户可以删 ...
- 初学c语言
虽然有一点点基础,但是还是从头学吧,这一周也就一些c语言的几个代码代表的意思和一个Hello world的程序. #include是头文件名,<>这是要返回的函数类型,然后是main主函数 ...
- java for循环
publicclass Test2 { staticboolean foo(char c) { System.out.print(c); returntrue; ...
- voa 2015 / 4 / 15
illustrated - v. to explain or decorate a story, book, etc., with pictures pediatrician – n. a docto ...