介绍

在js中,每个函数的原型都指向Function.prototype对象(js基于原型链的继承)。因此,每个函数都会有apply,call,和bind方法,这些方法继承于Function。

它们的作用是一样的,都是用来改变函数中this的指向。

使用方法

apply的用法可以表示如下:

A.apply(B, [x, y, z]);

此方法可以改变函数A的this指向,使之指向函数B。第二个参数传的是一个函数参数列表的数组形式。

call的用法和apply差不多,就只有传参方式不一样。类似于这样 :

A.apply(B, x, y, z)

可以把多个参数分开来传,而不是像apply一样,需要把所有参数放到一个数组里边传进来。

bind的传参方式和call一样,只不过它的不同之处是,apply和call方法调用之后会立即执行,而bind方法调用之后会返回一个新的函数,它并不会立即执行,需要我们手动执行。

举例

var name = "佚名";
var age = 20;
//global.name
//global.age var p1 = {
name: "张三",
age: 12,
func: function(){
console.log(`姓名:${this.name},年龄:${this.age}`)
}
} var p2 = {
name: "李四",
age: 15
} p1.func(); //姓名:张三,年龄:12
p1.func.call(); //姓名:佚名,年龄:20
p1.func.apply(p2); //姓名:李四,年龄:15
p1.func.bind(p2)(); //姓名:李四,年龄:15
  1. 当直接调用p1.func方法时,this指向的是当前p1这个对象,因此name和age都是它本身对象的属性值。
  2. 当使用call方法,传入的第一个参数为空时,在浏览器环境下,this指向window;在node环境下,this指向global。读者可自行把name和age改为global.name和global.age验证一下。
  3. 使用apply方法时,把p2传进去,相当于把函数的this指向p2对象,因此,此时打印出来的属性都是p2对象的属性
  4. 使用bind方法时,会生成一个新的函数对象,因此需要手动执行一下这个函数(即在函数末尾加个括号执行)。

总结

例子讲完,call,apply和bind的区别就已经很清楚了。它们就是为了改变this的上下文而存在。因此,有时候你会看到这样的用法。为了不改变this的指向,通常会在函数后边加上bind(this),如下

function f(){}.bind(this)

这样的话,就不会出现莫名其妙的this指向问题了。明明我想在函数里边调用此函数所属对象的某个属性时,为什么用this却访问不到呢。(写js的新手肯定会遇到过这种问题)

其实,从es6开始,已经支持箭头函数了,我建议大家用箭头函数,就不会出现this指向的问题了。

另外,使用call,apply还可以实现函数的继承。在es6的class没有出现之前,就需要借助它们来实现继承关系。

js中call、apply和bind到底有什么区别?的更多相关文章

  1. js中call、apply、bind到底有什么区别?bind返回的方法还能修改this指向吗?

     壹 ❀ 引 同事最近在看angularjs源码,被源码中各种bind,apply弄的晕头转向:于是他问我,你知道apply,call与bind的区别吗?我说apply与call是函数应用,指定thi ...

  2. JS中的apply,call,bind深入理解

    在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...

  3. js的call,apply,bind的使用与区别

    在原生js中会有三个很常见的函数,call,apply,bind 他们的作用就是改变当前函数的this指针, 但是细微来说他们还是有不同的. 1)call,apply都是执行某一函数,发现this有变 ...

  4. js中的apply与call的用法与区别

    call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受参数的 ...

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

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

  6. js 中call,apply,bind的区别

    call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...

  7. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  8. js中的text(),html() ,val()的区别

    js中的text(),html() ,val()的区别 text(),html() ,val()三个方法用于html元素的存值和取值,但是他们各有特点,text()用于html元素文本内容的存取,ht ...

  9. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

随机推荐

  1. 2019.4.22 python_Flag

    想了很久  最后觉得还是对编程的知识点好好重新的拉一边 回炉重造并不可笑 虽然从C到java到php到python 有两年的时间了 但是很多知识点都是零零碎碎,没有花时间复习和记录 所以决定从pyth ...

  2. 第六版PMBOK中工具与技术的介绍:数据收集数据分析数据表现

    数据收集技术: 1.头脑风暴:收集关于项目方法的创意和解决方案.2.焦点小组:召集预定的相关方和主题专家,了解他们对所讨论的产品服务或成果的期望和态度.主持人引导大家互动式讨论.3.访谈:通过与相关方 ...

  3. 利用ansible书写playbook在华为云上批量配置管理工具自动化安装ceph集群

    首先在华为云上购买搭建ceph集群所需云主机: 然后购买ceph所需存储磁盘 将购买的磁盘挂载到用来搭建ceph的云主机上 在跳板机上安装ansible 查看ansible版本,检验ansible是否 ...

  4. centos 7.6修改ssh端口,设置防火墙规则

    一.修改ssh端口 1 使用 root 用户进入 /etc/ssh目录 2 备份ssh配置文件 cp sshd_config sshd_config-bak 3 使用 vim 打开 sshd_conf ...

  5. The usage of Markdown---标题

    更新时间:2019.09.14 目录: 1. 序言 2. 标题   2.1 类Atx形式   2.2 类Setext形式 3. 总结 1. 序言   Markdown是一种纯文本的标记语言,只要熟悉M ...

  6. redis集群之Codis

    在大数据高并发场景下,单个 Redis 实例往往会显得捉襟见肘.首先体现在内存上,单个 Redis 的内存不宜过大,内存太大会导致 rdb 文件过大,进一步导致主从同步时全量同步时间过长,在实例重启恢 ...

  7. 数据结构(四十七)归并排序(O(nlogn))

    一.归并排序的定义 归并排序(Merging Sort)就是利用归并的思想实现的排序方法.它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n ...

  8. django-模板之自动转义autoescape(八)

    index.html {{QQ}} views.py def index(request): context={ 'QQ':'<a href="http://www.qq.com&qu ...

  9. Logstash 安装及简单实用(同步MySql数据到Elasticsearch)(Linux)

    1.下载logstash wget https://artifacts.elastic.co/downloads/logstash/logstash-6.6.0.tar.gz 2. 解压logstas ...

  10. 从零开始用刚买的阿里云实例搭建lnmp环境(非集成包)

    一.安装前 1. 更新系统软件: yum update 2. 查看是否已安装wget: rpm -qa wget 否则安装: yum install wget 3. 查看是否已安装编译器: rpm - ...