JavaScript 中的 apply、call、bind
在 JavaScript 中,apply、call、bind 是三个与函数调用相关的方法,它们都允许你在调用函数时手动设置函数的上下文(即 this 指向)。
1、apply 方法:apply 方法允许你调用一个函数,并且手动设置函数的上下文(即 this 指向)以及传递一个参数数组。其语法如下:
function.apply(thisArg, [argsArray])
其中,thisArg 表示函数要绑定的上下文,argsArray 是一个可选的数组,其中包含将传递给函数的参数列表。
例如,以下代码会将数组 [1, 2, 3] 作为参数传递给函数 foo,并且将函数的上下文设置为对象 obj:
function foo(a, b, c) {
console.log(a + b + c);
}
var obj = {
x: 1,
y: 2,
z: 3
};
foo.apply(obj, [1, 2, 3]); // 输出 6
2、call 方法:call 方法与 apply 方法类似,也是允许你调用一个函数,并且手动设置函数的上下文(即 this 指向),但是它需要你手动传递一个参数列表,而不是一个参数数组。其语法如下:
function.call(thisArg, arg1, arg2, ...)
其中,thisArg 表示函数要绑定的上下文,arg1、arg2、... 是将传递给函数的参数列表。
例如,以下代码会将参数 1、2、3 传递给函数 foo,并且将函数的上下文设置为对象 obj:
function foo(a, b, c) {
console.log(a + b + c);
}
var obj = {
x: 1,
y: 2,
z: 3
};
foo.call(obj, 1, 2, 3); // 输出 6
3、bind 方法:bind 方法与 apply、call 方法不同,它并不会立即调用函数,而是会返回一个新的函数,并且这个新函数的上下文(即 this 指向)被永久地绑定到了指定的对象上。其语法如下:
function.bind(thisArg, arg1, arg2, ...)
其中,thisArg 表示函数要绑定的上下文,arg1、arg2、... 是一些可选的参数,这些参数将在调用新函数时作为参数列表传递给原函数。
例如,以下代码会将函数 foo 的上下文绑定到对象 obj 上,并返回一个新函数 newFoo,当调用 newFoo 时,它的参数将被传递给原函数 foo:
function foo(a, b, c) {
console.log(a + b + c + this.x + this.y + this.z);
}
var obj = {
x: 1,
y: 2,
z: 3
};
var newFoo = foo.bind(obj, 1, 2, 3);
newFoo(); // 输出 12
除了以上的语法和使用方法之外,还有一些需要注意的点:
1、如果在使用 apply、call、bind 方法时没有传递 thisArg 参数或者传递了 null 或 undefined,那么默认的上下文将是全局对象(在浏览器环境中,通常是 window 对象)。
function foo() {
console.log(this === window); // 在浏览器环境中,输出 true
}
// 使用 apply 方法调用函数 foo,没有传递 thisArg 参数
foo.apply(); // 输出 true
// 使用 call 方法调用函数 foo,传递了 null 作为 thisArg 参数
foo.call(null); // 输出 true
// 使用 bind 方法绑定函数 foo 的上下文为 null,并创建一个新函数 newFoo
var newFoo = foo.bind(null);
newFoo(); // 输出 true
2、如果使用 bind 方法绑定了函数的上下文后,再使用 apply 或 call 方法调用这个函数,那么绑定的上下文将会被忽略,仍然使用传递给 bind 方法的上下文。
var obj1 = {
x: 1,
y: 2
};
var obj2 = {
x: 3,
y: 4
};
function foo() {
console.log(this.x + this.y);
}
// 使用 bind 方法绑定函数 foo 的上下文为 obj1,并创建一个新函数 newFoo
var newFoo = foo.bind(obj1);
// 使用 apply 方法调用新函数 newFoo,并将 obj2 作为上下文
newFoo.apply(obj2); // 输出 3
// 使用 call 方法调用新函数 newFoo,并将 obj2 作为上下文
newFoo.call(obj2); // 输出 3
在这个示例中,先使用 bind 方法将函数 foo 的上下文绑定为 obj1,并创建了一个新函数 newFoo。然后,分别使用 apply 和 call 方法调用新函数 newFoo,并将 obj2 作为上下文。由于使用了 bind
方法绑定了上下文,无论传递了什么参数,都不会改变绑定的上下文。这就是绑定的上下文被忽略的情况。最终输出的结果为 3,而不是 7。
3、如果使用 bind 方法绑定了函数的上下文后,再使用 new 操作符创建实例,那么绑定的上下文将被忽略,而是创建一个新的对象作为 this,并且原函数中的 this 将会指向这个新对象。
function Foo() {
this.x = 1;
this.y = 2;
}
var obj = {
x: 3,
y: 4
};
// 使用 bind 方法绑定函数 Foo 的上下文为 obj,并创建一个新函数 NewFoo
var NewFoo = Foo.bind(obj);
// 使用 new 操作符创建实例,此时会忽略绑定的上下文 obj,而是创建一个新对象作为 this
var newObj = new NewFoo();
console.log(newObj.x); // 输出 1
console.log(newObj.y); // 输出 2
console.log(obj.x); // 输出 3
console.log(obj.y); // 输出 4
在这个示例中,先使用 bind 方法将函数 Foo 的上下文绑定为 obj,并创建了一个新函数 NewFoo。然后,使用 new 操作符创建实例,此时会忽略绑定的上下文 obj,而是创建一个新对象作为 this。因此,实例 newObj 中继承了绑定函数 Foo 中定义的属性 x 和 y,输出 1 和 2。同时,原函数中的 this 指向了新创建的对象 newObj,因此在原函数中定义的属性 x 和 y 也被添加到了新对象上。
下面是一个示例,演示了使用 apply、call、bind 方法的一些特性:
function foo(a, b) {
console.log(this.x + this.y + a + b);
}
var obj1 = {
x: 1,
y: 2
};
var obj2 = {
x: 3,
y: 4
};
// 使用 apply 方法调用函数 foo,并将 obj1 作为上下文
foo.apply(obj1, [3, 4]); // 输出 10
// 使用 call 方法调用函数 foo,并将 obj2 作为上下文
foo.call(obj2, 5, 6); // 输出 18
// 使用 bind 方法绑定函数 foo 的上下文为 obj1,并创建一个新函数 newFoo
var newFoo = foo.bind(obj1, 7);
newFoo(8); // 输出 18
// 使用 bind 方法绑定函数 foo 的上下文为 obj2,并创建一个新函数 newFoo2
var newFoo2 = foo.bind(obj2);
newFoo2(9, 10); // 输出 26
综上所述,apply、call、bind 方法都是用于手动设置函数的上下文(即 this 指向),在实际开发中也经常被使用。对于这三个方法,需要了解它们的使用方法、语法和一些注意事项,以便在开发中更加灵活地使用它们。
JavaScript 中的 apply、call、bind的更多相关文章
- javascript中的apply,call,bind详解
apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...
- javascript中call,apply,bind的用法对比分析
这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们. 关于call,apply,bind这三个函数的用法,是学习java ...
- JavaScript中的apply()和call()
可以将call()和apply()看做是某个对象的方法,通过调用方法的形式来间接调用函数. call()和apply()的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对 ...
- Javascript中的apply、call、bind
apply . call .bind 三者都是用来改变函数的this对象的指向的: apply . call .bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文: apply . ...
- JavaScript中的new,bind,call,apply的简易实现
Function原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this 关键字密切相关,相当一部分人对它们的理解还是比较浅显,所谓js基础扎实,绕 ...
- 浅谈JavaScript中的apply,call和bind
apply,call,bine 这三兄弟经常让初学者感到疑惑.前两天准备面试时特地做了个比较,其实理解起来也不会太难. apply MDN上的定义: The apply() method calls ...
- JS中的apply,call,bind深入理解
在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...
- JavaScript中的apply和call函数详解(转)
每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,J ...
- JavaScript中call,apply和prototype
[TOC] call()方法 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 如果没有提供 thi ...
- JavaScript中的apply和call函数详解
本文是翻译Function.apply and Function.call in JavaScript,希望对大家有所帮助 转自“http://www.jb51.net/article/52416.h ...
随机推荐
- 【Android】Configuration中的locale已过时
Configuration中有很多属性的设置,在编译时提示错误说locale已过时这个是设置语言的 使用最新的方法如下 configuration.setLocale(locale);
- ajax 跨域请求jsonp
最近一段时间为这个事情走了不少弯路,现将成功经验分享,避免后来人再绕远路,不过也是第一次使用中间有什么问题大家可以留言探讨. ajax的跨域请求jsonp主要运用于不同系统的交互,一个系统想通过该种方 ...
- 第二十六节:urllib、requests、selenium请求库代理设置
1.urllib代理设置 1 from urllib.error import URLError 2 from urllib.request import ProxyHandler 3 from ur ...
- 4.10:Spark之wordcount
〇.概述 1.拓扑结构 2.目标 使用spark完成计数实验 一.启动环境 二.新建数据文件 三.查看文件内容 四.启动spark服务 五.编写代码 复制以下代码到shell中(复制后在终端右键-&g ...
- python中的数学函数
- STM32基本定时器控制LED闪烁代码
led.c #include "led.h" void LED_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2P ...
- 在Windows服务器安装禅道
1.服务器上 浏览器打开禅道官网:https://www.zentao.net/ 2.下载禅道版本,这里安装的是开源版 3.下载完成之后,一键安装 安装完成之后,即可访问:
- SQLMap入门——获取数据库用户的密码
列出数据库用户的密码 如果当前用户有读取包含用户密码的权限,SQLMap会先列举出用户,然后列出Hash,并尝试破解 python sqlmap.py -u http://localhost/sqli ...
- week_9(推荐系统)
Andrew Ng 机器学习笔记 ---By Orangestar Week_9(推荐系统) 1. Problem Formulation 这节就仅仅简单地介绍了一下 推荐系统的应用和实例.完全可以略 ...
- 还原火山引擎 A/B 测试产品——DataTester 私有化部署实践经验
作为一款面向ToB市场的产品--火山引擎A/B测试(DataTester)为了满足客户对数据安全.合规问题等需求,探索私有化部署是产品无法绕开的一条路. 在面向ToB客户私有化的实际落地中,火 ...