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);  //10

可以看到,刚开始对象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);  //5

当然, 如果在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();

原文地址:https://www.cnblogs.com/wphl-27/p/11526801.html

时间: 2024-08-03 01:47:55

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

php7中之局部变量,全局变量,超全局变量用法和区别

我们在使用php函数得时候遇到 ,局部变量,全局变量,超全局变量,如何灵活运用,php7中之局部变量,全局变量,超全局变量用法和区别? 1,局部变量 局部变量是在函数体内得变量,不能用外部得变量得值,只有当局部变量得值定义为全局变量才能使用外部变量得值 $a=1 function jj() { echo $a; } jj(); 2.全局变量 申明在函数外得变量,可以全局使用,使用关键词 global //global $a;$a="www.96net.com.cn";function

JavaScript中以构造函数的方式调用函数

转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明.函数表达式或者函数构造器(见以前的随笔)等方式来构造函数对象.函数构造器和其它函数的区别在与它们的调用方式不同. 要以构造函数的方式调用函数,只需要在调用时在函数名称前加new 关键字,比如:function whatsMyContext(){ return this; }; 调用:new what

【转】jQuery中的bind(),live(),delegate(),on()事件绑定方式的区别

bind()                                                                                                                                                                                                        简要描述 bind()向匹配元素添加一个或多个事件处理器. 使用方式 $(selecto

Javascript中的Bind 、Call和Apply

看以下代码: var bind = Function.prototype.call.bind(Function.prototype.bind); 第一眼看上去,我能猜出它究竟是用来做什么的.它把x.y(z)转化成了y(x,z). 编写良好的代码会比较容易被读懂.在读完Functional Javascript和 JavaScript Allongé (两本都是相当好的书)这两本书之后,再加上在Javascript函数式编程方面有些经验,弄懂上面这段代码的意思毫无压力.但是应该怎么向没有函数式编程

javascript中this、new、apply和call详解

如果在javascript语言里没有通过new(包括对象字面量定义).call和apply改变函数的this指针,函数的this指针都是指向window的,重要的话要说三遍.... 讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,javascript里的this指针逻辑上的概念也是实例化对象,这一点和c#语言里的this指针是一致的,但是javascript里的this指针却比c#里的this难以理解的多,究其根

JavaScript 中有关Array操作的一些函数

JavaScript的Array可以包含任意数据类型,并通过索引来访问每个元素. 要取得Array的长度,直接访问length属性: var arr = [1, 0.222, 'Hi', null, true,undefined]; alert(arr.length); //6 注意,如果直接给Array的length属性赋一个新的值会导致Array长度的改变: var arr = [1, 2, 3]; arr.length; // 3 arr.length = 6; arr; // arr变为

javascript中的bind()方法

ECMAScript还定义了一个方法:bind(). 这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值. window.color = "red"; var o = { color: 'blue' }; function sayColor(){ alert(this.color); } var objectSayColor = sayColor.bind(o); objectSayColor(); 在这里,sayColor()调用bind()并传入对象o,创

javascript 中 function bind()

Function bind() and currying <%-- All JavaScript functions have a method called bind that binds to an object and returns a new function. The first argument to bind sets the this context of the function. function area (height) { return this.width * he

JavaScript中常见的起来字符串操作函数及用法

http://www.midifan.com/moduleuser-index-430717.htmhttp://www.midifan.com/moduleuser-index-430547.htmhttp://www.midifan.com/moduleuser-index-430688.htmhttp://www.midifan.com/moduleuser-index-430540.htmhttp://www.midifan.com/moduleuser-index-430836.htm