js中call、apply和bind到底有什么区别?
介绍
在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
- 当直接调用p1.func方法时,this指向的是当前p1这个对象,因此name和age都是它本身对象的属性值。
- 当使用call方法,传入的第一个参数为空时,在浏览器环境下,this指向window;在node环境下,this指向global。读者可自行把name和age改为global.name和global.age验证一下。
- 使用apply方法时,把p2传进去,相当于把函数的this指向p2对象,因此,此时打印出来的属性都是p2对象的属性
- 使用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到底有什么区别?的更多相关文章
- js中call、apply、bind到底有什么区别?bind返回的方法还能修改this指向吗?
壹 ❀ 引 同事最近在看angularjs源码,被源码中各种bind,apply弄的晕头转向:于是他问我,你知道apply,call与bind的区别吗?我说apply与call是函数应用,指定thi ...
- JS中的apply,call,bind深入理解
在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...
- js的call,apply,bind的使用与区别
在原生js中会有三个很常见的函数,call,apply,bind 他们的作用就是改变当前函数的this指针, 但是细微来说他们还是有不同的. 1)call,apply都是执行某一函数,发现this有变 ...
- js中的apply与call的用法与区别
call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受参数的 ...
- 深入理解js中的apply、call、bind
概述 js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向. apply() apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作 ...
- js 中call,apply,bind的区别
call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...
- java中的NIO和IO到底是什么区别?20个问题告诉你答案
摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...
- js中的text(),html() ,val()的区别
js中的text(),html() ,val()的区别 text(),html() ,val()三个方法用于html元素的存值和取值,但是他们各有特点,text()用于html元素文本内容的存取,ht ...
- 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
浅谈JS中的!=.== .!==.===的用法和区别 var num = 1; var str = '1'; var test = 1; test == num //tr ...
随机推荐
- Cocos2d-x 学习笔记(11.2) RotateBy RotateTo
1. RotateBy RotateTo 两个旋转方法.RotateBy是在当前角度上旋转设置的角度.RotateTo是直接旋转到设置的角度,方向遵循“就近原则”.两者没有相互继承关系. 1.1 成员 ...
- 高通电源管理函数的power_supply的调用关系
以msm8909为例,高通的主要文件有几个: qpnp-linear-charger.c(线性充电器) qpnp-vm-bms.c(BMS管理) power_supply_core.c(power_s ...
- epoll--IO多路复用
理解 epoll 过程 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...
- 优化 .net core 应用的 dockerfile
优化 .net core 应用的 dockerfile Intro 在给 .net core 应用的写 dockerfile 的时候一直有个苦恼,就是如果有很多个项目,在 dockerfile 里写起 ...
- Oracle ADG环境搭建
部署 环境介绍 1,软件安装前基础部署 (两台做同样操作) 1.1,关闭selinux和防火墙 因为centos7里面没有/etc/sysconfig/iptables这个配置文件所以我们首先用yum ...
- 大觅网05Day
1.Mycat概述 在此前的服务器对数据库的存储数量要求并不高的时候,被经常使用的MySql数据基本能够满足对数据存储的要求. 但随着技术的不断发展,MySql甚至Redis都无法满足现今存储数量的指 ...
- Idea导入Web项目并发布到Tomcat
Idea导入现有的Web项目并发布到Tomcat,发现Tomcat没有自动发布 问题: 导入一个Web项目时,idea并没有把他当成web,所以需要自己修改项目结构 1.导入项目 打开 File-&g ...
- Airy Memory 内存清理 + 注册码
链接: https://pan.baidu.com/s/1ZGxDtJBMhrRtBISvL1Lv0w 提取码: ccjs
- sql中实现先排序后分组
数据表结构和数据如下: CREATE TABLE `commun_message_chat_single` ( `id` ) NOT NULL AUTO_INCREMENT, `chat_id` ) ...
- 证明:S = 1 + 1/2 + 1/4 + 1/8 + 1/16 + ·······,求证 S = 2
证: S = 1 + 1/2 + 1/4 + 1/8 + 1/16 + ······· (式1) 将式1左右两边除以2,得: S/2 = 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + ...