call、apply、bind方法的共同点与区别:

apply、call、bind 三者都是用来改变函数的this对象的指向;

apply、call、bind 三者都可以利用后续参数传参;

bind 是返回对应函数,便于稍后调用;apply、call则是立即调用。

一、call

1、   call(thisObj,x,y)

thisObj的取值有以下4种情况:

(1)不传,或者传null,undefined,函数中的this指向window对象;

(2)传递另一个函数的函数名,函数中的this指向这个函数的引用;

(3)传递字符串、数值或者布尔类型等基础类型,函数中的this指向其对应的包装对象,如string、number、boolean

(4)  传递一个对象,函数中的this指向这个对象

  1. function a(){
  2. console.log(this);
  3. }
  4.  
  5. function b(){}
  6.  
  7. var c={name: 'call'};
  8.  
  9. a.call(); // window
    a.call(null); //window
    a.call(undefined) //window
    a.call(1); // Number
    a.call(''); // String
    a.call(true) // Boolean
    a.call(b) // function b(){}
    a.call(c) // Object

2、 举个例子:

  1. function Animal(){
  2. this.name="animal";
    this.showName=function(){
    console.log(this.name);
    }
  3. }
    function Dog(){
    this.name = "dog";
    }
    var animal=new Animal();
    var dog = new Dog();
    animal.showName.call(dog);
  4.  
  5. 返回的是dog

因为dog继承了animal中showName 这个方法,但是this的指向还是dog,所有打印出来的是dog 中的name.

3、 call()在继承中的运用

  1. function Animal(name) {
    this.name=name;
    this.showName=function(){
    console.log(this.name);
    }
    }
    function Dog(name){
    Animal.call(this,name);
    }
    var dog = new Dog("Crazy dog");
    dog.showName();
    }
    输出:Crazy dog

传入了name 这个参数。

二、apply()

apply(thisObj,[argArray])

如果argArray 不是一个有效的数组或者不是arguments对象,那么将导致一个TypeError。

如果没有提供argArray 和thisObj 任何一个参数,那么Global对象将被用作thisObj, 并且无法被传递任何参数。

call 与apply 用法几乎是一样,只是传参的方式不一样。在js中,如果某个参数数量是不固定的,适合用apply,可以把参数push 进数组,传递进去。如果参数的数量是明确的,那就可以用cal。

三、bind

1、bind是在ES5 中扩展的方法(IE6,7,8不支持)

bind()方法与apply 和call很相似,也是可以改变函数体内的this的指向。

MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

  1. var bar=function(){
  2. console.log(this.x)
  3. }
  4.  
  5. var foo={
  6. x:3
  7. }
  8. bar()
  9. bar.bind(foo)();
  10.  
  11. var func=bar.bind(foo);
    func()
  12.  
  13. 输出:
    undefined
    3

2、如果连续bind()两次,艺或者是连续bind()三次,那么输出的值是什么?

  1. var bar = function(){
  2. console.log(this.x)
  3. }
  4. var foo = {
  5. x:3
  6. }
    var sed = {
    x:4
    }
    var func = bar.bind(foo).bind(sed);
    func();//
    var fiv = {
    x:5
    }
    var func = bar.bind(foo).bind(sed).bind(fiv);
    func();

答案都是3。原因是,在js中,多次bind()是无效的。

四、总结apply、call、bind比较

  1. var obj = {
  2. x: 81
  3. }
  4.  
  5. var foo = {
  6. getX: function() {
  7. return this.x;
  8. }
  9. }
  10.  
  11. console.log(foo.getX.bind(obj)()); //
  12. console.log(foo.getX.call(obj)); //
  13. console.log(foo.getX.apply(obj)); //

三个输出是81,但是注意看使用bind()方法,后面多了对括号。

区别是:当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用bind()方法。而apply/call则会立即执行函数。

再总结一下:

apply、call、bind 三者都是用来改变函数的this对象的指向的;

apply、call、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

apply、call、bind 三者都可以利用后续参数传参;

bind是返回对应函数,便于稍后调用;apply、call则是立即调用。

js 中call,apply,bind的区别的更多相关文章

  1. JS中call,apply,bind的区别

    1.关于this对象的指向,请看如下代码 var name = 'jack'; var age = 18; var obj = { name:'mary', objAge:this.age, myFu ...

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

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

  3. 深入理解js中的apply、call、bind

    概述 js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向. apply() apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作 ...

  4. JS 的 call apply bind 方法

    js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[,   [,.argN]]]] ...

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

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

  6. JS中isPrototypeOf 和hasOwnProperty 的区别 ------- js使用in和hasOwnProperty获取对象属性的区别

    JS中isPrototypeOf 和hasOwnProperty 的区别 1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的 ...

  7. (网页)Angular.js 中 copy 赋值与 = 赋值 区别

    转自st.gg Angular.js 中 copy 赋值与 = 赋值 区别 为什么用 $scope.user = $scope.master; $scope.master 会跟着 $scope.use ...

  8. js中的substr和substring区别

    js中的substr和substring区别 Substring: 该方法可以有一个参数也可以有两个参数. (1)  一个参数: 示例: var str=“Olive”: str.substring( ...

  9. JS 中的require 和 import 区别整理

    ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使 ...

随机推荐

  1. ngrinder的安装

    1.官网下载war包(ngrinder-controller),可以使用tomcat启动或者直接nohup java -XX:Permsize=200m -jar ngrinder-3.4.1.war ...

  2. SQL 随机取出一条数据

    今天遇到一需求,需要随机取出一条数据.网上找了下,sqlserver自带的有newID()这个函数,可以随机出来一个guid,用来取随机数还是蛮不错的. 直接上SQL: select top 1 *, ...

  3. 使用注解开发springmvc

    1.导入jar包 commons-logging-1.2.jar spring-aop-4.3.6.RELEASE.jar spring-beans-4.3.6.RELEASE.jar spring- ...

  4. 漫话最小割 part1

    codeforces 724D [n个城市每个城市有一个特产的产出,一个特产的最大需求.当i<j时,城市i可以运最多C个特产到j.求所有城市可以满足最大的需求和] [如果直接最大流建图显然会T. ...

  5. Windows下配置scrapy需要MVC的14.0版本(转载)

    转载于--http://blog.csdn.net/MrWilliamVs/article/details/77130965 杨煜冬煜杨的博客,他的博客比较杂,Java.Python都有--http: ...

  6. php执行超时(nginx,linux环境)

    与下面的参数有关 nginx: fastcgi_connect_timeout fastcgi_read_timeout fastcgi_send_timeout php-fpm:request_te ...

  7. 【js html】对于<img>图片的引用填充,src可以给什么值?

    平时多见的<img>的使用,常见于如下: <img class="img-responsive img-rounded" src="static/img ...

  8. 将一个文件从gbk编码转换为utf8编码

    用django展示模板时,出现如下错误: 'utf8' codec can't decode byte 0xd3 in position 197: invalid continuation byte ...

  9. 【手记】走近科学之为什么JObject不能调用LINQ扩展方法

    Json.NET的JObject明明实现了IEnumerable<T>,具体来说是IEnumerable<KeyValuePair<string, JToken>> ...

  10. PostgreSQL 源码解读 node的模拟实现

      node的实现是PostgreSQL的查询解析的基础,实现的关键是两个宏,makeNode和newNode.其他节点继承自Node节点,如果增加新的结构体,需要添加NodeTag中添加对应的枚举值 ...