博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈JavaScript中的apply、call和bind
阅读量:7208 次
发布时间:2019-06-29

本文共 1859 字,大约阅读时间需要 6 分钟。

摘要

  • 三种方法均可改变函数this关键字的指向。
  • apply()接受一参数数组,返回函数执行的结果。
  • call()接受一组参数,返回函数执行的结果。
  • bind()接受一组参数,返回函数体。需在bind()后加小括号才能执行函数。
  • 箭头函数的this绑定后无论使用apply()call()还是bind()都不可修改。

浅析this关键字

  • JavaScript中的函数存在定义上下文运行上下文,通过call()apply()bind()可以改变this的指向。
  • this总指向运行上下文

定义上下文

定义上下文更准确的名称应该叫词法作用域,它指函数的定义部分所形成的作用域。

function fun1 () {	// 函数fun1的词法作用域	// 函数定义	// ....}复制代码

运行上下文

函数在调用时会产生一个调用记录,其中包含函数在哪里被调用、传入函数的参数等信息。该记录也被称为运行上下文。一个函数的this总指向函数的运行上下文。当fun1fun2中调用时,fun1this指向fun2的定义上下文(词法作用域)。

function fun2 () {    // fun1的this指向该作用域    fun1();    // 函数定义    // ...}复制代码

this的指向

this是运行上下文的一个属性,因此常说this指向函数的运行上下文

this是在函数调用时被绑定的,与函数的声明位置(即词法作用域)没有任何关系。


call()apply()

call()

call()方法的第一个参数为要指定的this对象,第二个参数及以后为函数运行所需的参数列表。

let obj = {    a: 1}function fun1 (num1, num2) {    console.log(this); // obj {a: 1}    console.log(num1 + num2); // 3    console.log(this.a); // 1}fun1.call(obj, 1, 2);复制代码

上述代码展示了call()的两种能力。一方面它改变了fun1调用时的this关键字,让其指向obj,并通过this关键字来访问obj中的属性。另一方面它将自己接受到的参数传入fun1

apply()

call()apply()本质上并无太大差别,唯一的区别在于call()接受的是参数列表,而apply()接受的是一个参数数组。

// ··· 同上    fun1.apply(obk, [1, 2]); // 效果和fun1.call(obj, 1, 2)相同复制代码

bind()

bind()创建一个新的函数, 当这个新函数被调用时this键值为其提供的值,其参数列表前几项值为创建时指定的参数序列。          -----

bind()的使用方法和call()十分类似,它的第一个参数是需要绑定的this对象,之后的参数为函数运行所需的参数列表。下面让我们来试验一下。

let obj = {    a: 1}function fun1 (num1, num2) {    console.log(this);    console.log(num1 + num2);    console.log(this.a);}fun1.bind(obj, 1, 2); // fun1 { ··· }复制代码

不同于apply()call()bind()返回的并不是fun1执行完毕的返回值,而是更改了this并初始化参数之后的fun1的函数定义。因此,要执行fun1,需在bind()后面再加一对括号:

fun1.bind(obj, 1, 2)(); // 改变this并传入参数后执行fun1复制代码

apply()call()bind()的比较

相同点

  • 均可改变函数this关键字的指向。

不同点

  • apply()接受一参数数组,返回函数执行的结果。
  • call()接受一组参数,返回函数执行的结果。
  • bind()接受一组参数,返回函数体。需在bind()后加小括号才能执行函数。

箭头函数的this绑定

ES6中新加入了箭头函数,它的绑定完全继承自调用它的作用域。绑定后无论使用apply()call()还是bind()都不可修改

转载于:https://juejin.im/post/5c00d2a9518825653a2325ea

你可能感兴趣的文章
Android学习笔记技巧之垂直和水平滚动视图
查看>>
周练1
查看>>
SpringSecurity实现后台管理员登录(二)
查看>>
LinkedList的一种错误使用方法
查看>>
开源框架Quartz动态加入、改动和删除定时任务 (二)
查看>>
Android——Activity的生命周期
查看>>
移位操作之旋转移位
查看>>
一个忙着找实习工作的大三在校生的真实感受!!!
查看>>
installed jre指向jdk而非jre位置&
查看>>
C#导出Excel按照指定格式设置单元格属性值
查看>>
栈与队列问题(主要是栈的使用)
查看>>
OAuth
查看>>
21分钟 MySQL 入门教程
查看>>
610. 数对的个数
查看>>
Bash中的括号(三)
查看>>
Ural 1353 Milliard Vasya's Function(DP)
查看>>
Pause Web Sessions
查看>>
JS获取当前时间戳的方法
查看>>
利用content为伊特元素追加三个小点
查看>>
【Mysql】将Excel表导入至Mysql的当中一张表
查看>>