关于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():的更多相关文章

  1. Javascript中call,apply,bind方法的详解与总结

    在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...

  2. Javascript中call、apply、bind函数

    javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...

  3. Javascript中call,apply,bind的区别

    一.探索call方法原理 Function.prototype.call = function(obj) { // 1.让fn中的this指向obj // eval(this.toString().r ...

  4. JavaScript 中call()、 apply()、 bind()改变this指向理解

    最近开发的过程中遇到了this指向问题,首先想到的是call().apply().bind()三个方法,有些时候这三个方法确实是十分重要,现在我们就把他们的使用方法及异同点讲解一下. 1.每个函数都包 ...

  5. JavaScript中call、apply、bind、slice的使用

    1.参考资料 http://www.cnblogs.com/coco1s/p/4833199.html   2.归结如下 apply . call .bind 三者都是用来改变函数的this对象的指向 ...

  6. javascript中call()、apply()、bind()的用法终于理解

    其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例1 obj.objAge;  //17 obj.myFun()  //小张年龄undefined 例2 shows( ...

  7. (转)javascript中call()、apply()、bind()的用法

    其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例1 obj.objAge;  //17 obj.myFun()  //小张年龄undefined 例2 shows( ...

  8. javascript中call、apply、bind详解

    1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定 ...

  9. JavaScript 中 call,apply 和 bind

    call and apply   改变函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数. function test() {} test() == test.ca ...

  10. javascript中call()、apply()、bind()的用法理解

    一.bind的用法 第一个:obj.showInfo('arg','arg_18');中传的2个参数通过showInfo方法改变的是obj下中的name和age 第二个:obj.showInfo.bi ...

随机推荐

  1. 深入理解PHP对象注入

    0x00 背景 php对象注入是一个非常常见的漏洞,这个类型的漏洞虽然有些难以利用,但仍旧非常危险,为了理解这个漏洞,请读者具备基础的php知识. 0x01 漏洞案例 如果你觉得这是个渣渣洞,那么请看 ...

  2. thinkphp中find()和select()的区别

    1.find()是查找符合条件的第一条数据,返回的是一个一维数组: select()是查找符合条件的所有的数据,返回的是一个二维数组: 2.以下案例 $tech=M('techlevel','HR_C ...

  3. 【CC2530入门教程-03】CC2530的中断系统及外部中断应用

    第3课  CC2530的中断系统及外部中断应用 广东职业技术学院  欧浩源 一.中断相关的基础概念  内核与外设之间的主要交互方式有两种:轮询和中断. 轮询的方式貌似公平,但实际工作效率很低,且不能及 ...

  4. java 线程的死锁问题

    以下的情况可能出现死锁 1.一个对象的同步方法去调用另一个对象的同步方法,同时另一个对象的同步方法也在调用这个对象的同步方法,导致一定几率的死锁,不一定每次都会出现死锁,模拟的代码如下 package ...

  5. nginx常用配置系列-HTTPS配置

    接上篇,nginx配置系列 HTTPS现在已经很流行,特别是AppStore上线的应用要求使用HTTPS进行通信,出于安全考虑也应该使用HTTPS,HTTPS配置需要准备证书文件,现在也有很多免费证书 ...

  6. BigDecimal四舍五入使用总结

    //BigDecimal四舍五入double f1 = new BigDecimal(1).setScale(2,RoundingMode.HALF_UP).doubleValue();//转化成字符 ...

  7. Redis的安装与使用(单节点)

    IP:192.168.4.111 环境:CentOS 6.6 Redis版本:redis-3.0 (考虑到Redis3.0在集群和性能提升方面的特性,rc版为正式版的候选版,而且很快就出正式版) 安装 ...

  8. linux 小技巧(查找替换文件中的ascii编码字符)

    这里纪录一些linux下用到的小技巧,以免遗忘 在linux中经常碰见各种文件处理.最常用的就是替换文件中的某些字符.常见字符替换还是很容易完成.但是有些不可见字符以及ascii编码字符等等都无法直接 ...

  9. Backbone中父子view之间的值传递

    backbone中,使用最多的莫过于在view中进行操作,如模板的渲染以及事件函数的定义.为了提高代码的可维护性,一般地我们会写多个视图即view,将界面按照功能的不同进行模块化划分,模块与view一 ...

  10. NPOI 生成 excel基本设置

    //设置页眉页脚 tempSheet.Header.Center = "2017-04-27"; tempSheet.Footer.Center = "√" + ...