一直没怎么使用过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();

JavaScript中的bind,call和apply函数的用法和区别的更多相关文章

  1. SQL 中详解round(),floor(),ceiling()函数的用法和区别?

    SQL 中详解round(),floor(),ceiling()函数的用法和区别? 原创 2013年06月09日 14:00:21   摘自:http://blog.csdn.net/yueliang ...

  2. sql中详解round(),floor(),ceiling()函数的用法和区别?

    round() 遵循四舍五入把原值转化为指定小数位数,如:round(1.45,0) = 1;round(1.55,0)=2floor()向下舍入为指定小数位数 如:floor(1.45,0)= 1; ...

  3. Javascript中的bind()函数

    今天看到公司大神的一段代码: function ReplaceProcessor() { this._dom = { btnReplace: $('#ro_btnReplace'), btnCompl ...

  4. javascript 中的 bind (编辑中。。。。)

    这篇文章说的非常好!http://my.oschina.net/blogshi/blog/265415 我的体会就是,函数中的this,指的是运行时,它是被哪个对象调用的.因为javascrpit的函 ...

  5. 把玩Javascript中的bind

    前言 今天闲着无聊随便逛了逛MDN,忽而看到一个方法Function.prototype.bind(),突然发现除了使用这个方法之外都没有仔细琢磨过这个方法.于是乎,找到了kill time的事情-写 ...

  6. Javascript中的bind详解

    前言 用过React的同学都知道,经常会使用bind来绑定this. import React, { Component } from 'react'; class TodoItem extends ...

  7. JavaScript中的bind方法及其常见应用

    一.bind()方法的实现 在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用.就拿最常见的console.log("info…")来说,避免书写 ...

  8. 理解JavaScript中的arguments,callee,caller,apply

    arguments 该对象代表正在执行的函数和调用它的函数的参数. [function.]arguments[n] 参数function :选项.当前正在执行的 Function 对象的名字. n : ...

  9. [转] 理解 JavaScript 中的 Array.prototype.slice.apply(arguments)

    假如你是一个 JavaScript 开发者,你可能见到过 Array.prototype.slice.apply(arguments) 这样的用法,然后你会问,这么写是什么意思呢? 这个语法其实不难理 ...

随机推荐

  1. 《python解释器源码剖析》第7章--python中的set对象

    7.0 序 集合和字典一样,都是性能非常高效的数据结构,性能高效的原因就在于底层使用了哈希表.因此集合和字典的原理本质上是一样的,都是把值映射成索引,通过索引去查找. 7.1 PySetObject ...

  2. Binlog_master

    二进制日志 记录导致数据改变或潜在导致数据改变的SQL语句 记录已提交的日志 不依赖于存储引擎类型 功能:通过"重放"日志文件中的事件来生成数据副本 注意:建议二进制日志和数据文件 ...

  3. maven报错 java.lang.RuntimeException: com.google.inject.CreationException: Unable to create injector, see the following errors

    2 errors java.lang.RuntimeException: com.google.inject.CreationException: Unable to create injector, ...

  4. MyBatis-04-配置解析

    4.配置解析 1.核心配置文件 mybatis-config.xml MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息 configuration(配置) propertie ...

  5. HTTPClick调用WebApi帮助类

    1.创建ApiHelper类 2.复制以下代码到类中 using System; using System.Collections.Generic; using System.Linq; using ...

  6. .npy文件怎么打开

    import numpy as np test = np.load(r'C:\Users\SAM\PycharmProjects\TEAMWORK\Preprocess_3D\muchdata-50- ...

  7. python读取csv文件的某一列或某几列

    import csvimport pandas as pd with open('D:\Data\新建文件夹\list3.2.csv','r') as csvfile: reader = csv.re ...

  8. Struct2的简单的CRUD配置和使用

    1. 首先是Struct2使用的jar包,可以在官网下载https://struts.apache.org/   ,其中包只要下面这些就够用了. 或者点击下面链接下载 链接:https://pan.b ...

  9. Mybatis 解决问题的记录与博客

    问题:mybatis 空值映射的问题Mybatis在使用resultMap来映射查询结果中的列,如果查询结果中包含空值的列(不是null),则Mybatis在映射的时候,不会映射这个字段 https: ...

  10. Spring前置方法无法阻止原方法执行(转)

    在前置方法用return的方法无法阻止原方法的执行. 该处的return 只是结束了目标方法执行前的检验方法而已,而不是结束目标方法. 使用抛异常的方式程序终止. 环绕通知可以阻止原方法的执行, pu ...