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

  1、每个函数都包含三个非继承而来的方法,call()方法、apply()方法和bind()方法

      2、相同点:三者的作用都是一样的,都是在特定作用中调用函数,等于设置函数体内this的值,以扩充函数赖以运行的作用域。

  一般来说,this总是指向调用某个方法的对象,但是使用call()、apply()和bind()方法时,就会改变this的指向。

  3、不同点:

    1)、bind()方法会返回一个函数,将接受多个参数的函数变换成接受一个单一参数。

      注意:bind(thisArg[, arg1[, arg2[, ...]]]), 将接受多个参数的函数变换成接受一个单一参数。bind()方法所返回的函数的length(形参数量)等于原函数的形参数量减去传入bind()方法中的实参数量(第一个参数以后的所有参数),因为传入bind中的实参都

      会绑定到原函数的形参。

    2)、apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。

      注意:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象

      将用作thisObj。

    3)、call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。

      注意:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有

      提供thisObj参数,那么Global对象被用于thisObj。

   话不多说,上代码:

  

 //例1
<script>
window.color = 'red';
document.color = 'yellow'; var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
} changeColor.call(); //red (默认传递参数)
changeColor.call(window); //red
changeColor.call(document); //yellow
changeColor.call(this); //red
changeColor.call(s1); //blue </script> //例2
var Pet = {
words : '...',
speak : function (say) {
console.log(say + ''+ this.words)
}
}
Pet.speak('Speak'); // 结果:Speak... var Dog = {
words:'Wang'
} //将this的指向改变成了Dog
Pet.speak.call(Dog, 'Speak'); //结果: SpeakWang

call的用例代码

 //例1
<script>
window.number = 'one';
document.number = 'two'; var s1 = {number: 'three' };
function changeColor(){
console.log(this.number);
} changeColor.apply(); //one (默认传参)
changeColor.apply(window); //one
changeColor.apply(document); //two
changeColor.apply(this); //one
changeColor.apply(s1); //three </script> //例2
function Pet(words){
this.words = words;
this.speak = function () {
console.log( this.words)
}
}
function Dog(words){
//Pet.call(this, words); //结果: Wang
Pet.apply(this, arguments); //结果: Wang
}
var dog = new Dog('Wang');
dog.speak();

apply的用例代码

 var test = {
a : 5,
b : 6,
sum : function (a,b) {
var self = this;
function getA() {
return self.a;
}
function getB(){
return self.b;
}
alert(a);
alert(b);
return getA() + getB();
}
}
var obj = {a:2,b:3};
alert(test.sum.call(obj,4,5)); // 调用时self = this = obj,alert顺序4,5,5
alert(test.sum.apply(obj,[6,7])); // 调用时self = this = obj,alert顺序6,7,5
var sum = test.sum.bind(obj,8); // 此处返回一个只有一个参数的函数sum(b)
alert(sum(9)); // 调用时self = this = obj,alert顺序8,9,5

bind的用例代码

   

  总结:
    1、call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象
    2、call的参数是直接放进去的,第二第三第n个参数全都用逗号分隔
    3、apply的所有参数都必须放在一个数组里面传进去
    4、bind除了返回是函数以外,它的参数传递方式和call 一样。    
    当然,三者的参数不限定是string类型,允许是各种类型,包括函数 、 object 等等!

JavaScript 中call()、 apply()、 bind()改变this指向理解的更多相关文章

  1. javascript中call,apply,bind的用法对比分析

    这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们.   关于call,apply,bind这三个函数的用法,是学习java ...

  2. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  3. JavaScript中call,apply,bind方法的总结

    原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...

  4. JavaScript中call,apply,bind方法的区别

    call,apply,bind方法一般用来指定this的环境. var a = { user:"hahaha", fn:function(){ console.log(this.u ...

  5. JavaScript中call,apply,bind方法

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  6. javascript中call,apply,bind的使用

    不同点: 1.call():传参方式跟bind一样(都是以逗号隔开的传参方式),但是跟apply(以数组的形式传参)不一样, 2.bind(): 此方法应用后的情形跟call和apply不一样.该方法 ...

  7. 借助JavaScript中的Dom属性改变Html中Table边框的颜色

    借助JavaScript中的Dom属性改变Html中Table边框的颜色 -------------------- <html> <head> <title>我是页 ...

  8. 借助JavaScript中的时间函数改变Html中Table边框的颜色

    借助JavaScript中的时间函数改变Html中Table边框的颜色 <html> <head> <meta http-equiv="Content-Type ...

  9. javascript中的apply,call,bind详解

    apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...

随机推荐

  1. Ie浏览器请求400错误,谷歌火狐等浏览器正常请求.

    做项目的时候,遇到一个小的问题.一个location.href="请求的url"在其它浏览器上是可以正常请求的.但是在ie浏览器上确出现奇怪的http请求400错误,我们先来对于h ...

  2. python线程信号量semaphore(33)

    通过前面对 线程互斥锁lock /  线程事件event / 线程条件变量condition / 线程定时器timer 的讲解,相信你对线程threading模块已经有了一定的了解,同时执行多个线程的 ...

  3. ufile开公钥私钥

    https://docs.ucloud.cn/storage_cdn/ufile/guide/token登陆UCloud官方控制台,进入UFile—令牌管理

  4. Beginning Linux Programming 学习-chapter2-Shell programming-Pipes and Redirection

    "为了从事创造性工作,人类需要孤独,可是在孤独中,广义的人类仍存在于内心."--(德国)奥铿                                             ...

  5. webstorm 2019.1.3 破解

    2019.11.28日,已过期,出门右转 https://blog.csdn.net/ft_sunshine/article/details/92065158 1.修改host文件,末尾添加 0.0. ...

  6. MySQL和Oracle的区别与不同

    一.mysql与Oracle的相同点: 1.都是关系型数据库管理系统(MySQL开放源码) 2.都是目前很流行的数据库(Oracle以分布式为核心): 二.MySQL.Oracle各自特点: 1.Or ...

  7. Linux (x86) Exploit 开发系列教程之二(整数溢出)

    (1)漏洞代码 //vuln.c #include <stdio.h> #include <string.h> #include <stdlib.h> void s ...

  8. 20191011-构建我们公司自己的自动化接口测试框架-testrun最重要的模块

    testrun模块呢就是最终自动化测试入口,调用前面封装的各个模块主要流程是: 1. 获取测试集种待执行的测试用例 2. 处理测试用例获取的数据,包括转换数据格式,处理数据的中的关联等 3. 处理完数 ...

  9. 使用Duilib开发Windows软件(4)——消息传递

    云信Duilib中没有窗体类的函数可以用来直接收取到所有控件的事件,每个控件都可以单独设置自己的事件处理函数,一般在InitWindow方法中初始化各个控件的事件处理函数. 每个控件都有许多形如Att ...

  10. (三)Spring框架之事务管理

    一.编程式事务管理 Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,事务管理器接口PlatformT ...