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

JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

call可以传递一个thisArgs参数和一个参数列表,thisArgs 指定了函数在运行期的调用者,也就是函数中的 this 对象,而参数列表会被传入调用函数中。thisArgs 的取值有以下4种情况:
(1) 不传,或者传null,undefined, 函数中的 this 指向 window 对象
(2) 传递另一个函数的函数名,函数中的 this 指向这个函数的引用
(3) 传递字符串、数值或布尔类型等基础类型,函数中的 this 指向其对应的包装对象,如 String、Number、Boolean
(4) 传递一个对象,函数中的 this 指向这个对象

function a() {
console.log(this); //输出函数a中的this对象
}
function b() {} //定义函数b var obj = {
name: 'hehe'
}; //定义对象obj 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(obj); //Object

这是call 的核心功能,它允许你在一个对象上调用该对象没有定义的方法,并且这个方法可以访问该对象中的属性。

function animals() {}
animals.prototype = {
type: "dog",
say: function() {
console.log("I am a " + this.type);
}
}
var dog = new animals();
dog.say(); //I am a dog
var cat = {type:'cat'};
dog.say.call(cat); //I am a cat

因此,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中cat没有say方法),但是其他的有(本栗子中dog有say方法),我们可以借助call或apply用其它对象的方法来操作。

apply、call 的区别:

对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。

对象.函数名.call(thisArgs, arg1, arg2);
对象.函数名.apply(thisArgs, [arg1, arg2])

其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

- bind:
bind是ES5 新增的一个方法,它的传参和call类似,但又和 call/apply 有着显著的不同,即调用 call 或 apply 都会自动执行对应的函数,而 bind 不会执行对应的函数,只是返回了对函数的引用。

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

var obj = {
id : 1,
eventBind: function(){
var _this = this;
$('.btn').on('click',function(event) {
alert(this.id); //undefined
alert(_this.id); //1
});
}
}
obj.eventBind();//没有这句话,click事件不执行

由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $('.btn').on('click',function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:

var obj = {
id : 1,
eventBind: function(){
$('.btn').on('click',function(event) {
alert(this.id); //1
}.bind(this));
}
}
obj.eventBind();//没有这句话,click事件不执行

- call、apply和bind的区别:

var obj = {
x: 88,
};
var foo = {
getX: function() {
return this.x;
}
}
console.log(foo.getX.bind(obj)()); //88
console.log(foo.getX.call(obj)); //88
console.log(foo.getX.apply(obj)); //88

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

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

本文转载于:猿2048https://www.mk2048.com/blog/blog.php?id=h1kk2jkj0ib

call、apply和 bind的简单使用方法的更多相关文章

  1. Javascript中call,apply,bind方法的详解与总结

    在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...

  2. 继承:call、apply、bind方法

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

  3. JavaScript中的call、apply、bind方法的区别

    在JavaScript 中,this的指向是动态变化的,很可能在写程序的过程中,无意中破坏掉this的指向,所以我们需要一种可以把this的含义固定的技术,于是就有了call,apply 和bind这 ...

  4. JS进阶系列之this (call、apply、bind)

    在javascript中,this的指向是在执行上下文的创建阶段确定的,其实只要知道不同执行方式下,this的指向分别是是什么,就能很好的掌握this这个让人摸不透的东西. 一.全局执行 全局执行又分 ...

  5. call,apply,bind的用法与区别

    1.call/apply/bind方法的来源 首先,在使用call,apply,bind方法时,我们有必要知道这三个方法究竟是来自哪里?为什么可以使用的到这三个方法? call,apply,bind这 ...

  6. 对于call,apply,bind 的理解

    JavaScript 中 call().apply().bind() 的用法 之前对与JavaScript中的call,apply,bind这几个方法一直理解的很模糊,今天总结一下. 例1 var n ...

  7. 有关call和apply、bind的区别及this指向问题

    call和apply都是解决this指向问题的方法,唯一的区别是apply传入的参数除了其指定的this对象之外的参数是一个数组,数组中的值会作为参数按照顺序传入到this指定的对象中. bind是解 ...

  8. 简单模拟实现javascript中的call、apply、bind方法

    目录 引子 隐式丢失 硬绑定 实现及原理分析 总体实现(纯净版/没有注释) 写在最后 引子 读完<你不知道的JavaScript--上卷>中关于this的介绍和深入的章节后,对于this的 ...

  9. JS中的call、apply、bind方法

    JS中的call.apply.bind方法 一.call()和apply()方法 1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]] ...

随机推荐

  1. Go标准的目录结构(自总结)

    微服务版 ├── LICENSE.md ├── Makefile //在任何一个项目中都会存在一些需要运行的脚本,这些脚本文件应该被放到 /scripts 目录中并由 Makefile 触发 ├── ...

  2. Jmeter--由PV估算tps和最大并发数

    需求 "假设一个系统的业务有登录.浏览帖子.发送新贴.回复帖子,访问高峰是上午10点,日访问高峰PV约5208(含登录1300.浏览2706.发帖526.回帖676).系统响应时间要求小于3 ...

  3. 2. Java入门

    2.Java入门 2.1.安装开发环境 卸载JDK 删除Java的安装目录 删除JAVA_HOME 删除path下关于Java的目录 java -version 安装JDK 百度搜索JDK8,找到下载 ...

  4. php简易表单及下拉框动态渲染

    <?php//1.连接数据库$link = mysqli_connect('127.0.0.1','root','root','1906');//2.设置字符集mysqli_set_charse ...

  5. 如何实现 UITabbarController 的 State Preservation?

    原文链接 最近在看ios programming - the big nerd ranch guide 这本书,其中第24章介绍了如何使用系统接口来实现 State Restoration. 示例部分 ...

  6. 解决移动端ios网页端收起键盘导致的页面空白问题

    一句代码就搞定了,只要失焦的时候把窗口滚动位置设置到(0,0)就行了 <input type="text" onblur="window.scrollTo(0, 0 ...

  7. 记一次解决关机蓝屏 | MULTIPLE_IRP_COMPLETE_REQUESTS | klflt.sys

    已经解决蓝屏问题,原因是卡巴斯基安全软件驱动导致,需要卸载卡巴斯基安全软件,详细过程如下. 一.关机时蓝屏 Win10系统,在关机动画快结束时突然蓝屏,提示:你的设备遇到问题,需要重启,终止代码:MU ...

  8. 顺序表的插入和删除(基于c语言)

    插入:在下标p处插入数据x:返回是否成功(0/1) 几个注意点:1.还能否插入数据:2.给的下标p是否是错误的以及p的范围:3.移动时的易错点(从下标大的元素开始):4.n与palist->n; ...

  9. unittest 测试用例实现

    unittest框架结构 test_case: 测试套件,每一个.py文件代表一个测试用例,测试用例以test开头,否则框架读取不到测试用例 __init__.py是做什么的? 要弄明白这个问题,首先 ...

  10. 通过rem自适应屏幕尺寸

    通过rem自适应屏幕尺寸 常用的前端单位 px px就是pixel的缩写,设备分辨率,物理像素 pt pt就是point的缩写,逻辑分辨率,逻辑像素 em 参考物是父元素的font-size,具有继承 ...