16.call、apply、bind区别

3/1/2023 笔记

相同点:改变函数执行的上下文。简言之就是改变this指向

# 1.call

  1. 语法、参数、返回值
function.call(thisArg, arg1, arg2, ...)

// thisArg:可选的。
// arg1, arg2, ...:指定的参数列表

// 返回值:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined
1
2
3
4
5
6
  1. 案例
// 1.使用 call 方法调用函数并且不指定第一个参数
var sData = 'Wisen';
function display() {
  console.log('sData value is %s ', this.sData);
}
display.call();  // sData value is Wisen

// 备注: 在严格模式下,this 的值将会是 undefined。见下文。
'use strict';
var sData = 'Wisen';
function display() {
  console.log('sData value is %s ', this.sData);
}
display.call(); // Cannot read the property of 'sData' of undefined

// 2.使用 call 方法调用函数并且指定上下文的 'this'
// 当调用 greet 方法的时候,该方法的this值会绑定到 obj 对象。
function greet() {
  var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
  console.log(reply);
}
var obj = {
  animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj);  // cats typically sleep between 12 and 16 hours

// 3.普通用法
var a = {
  name: "cherry",
  fn: function(a, b) {
    console.log(a + b);
  }
};
var b = a.fn;
b.call(a, 1, 3)  // 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 2.apply

  1. 语法、参数、返回值
apply(thisArg)
apply(thisArg, argsArray)

// thisArg:在 func 函数运行时使用的 this 值。请注意,this 可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
// argsArray:可选。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。

// 返回值:调用有指定this值和参数的函数的结果
1
2
3
4
5
6
7

  1. 虽然这个函数的语法与 call() 几乎相同,但根本区别在于,call() 接受一个参数列表,而 apply() 接受一个参数的单数组。
  2. 当第一个参数为 null 或 undefined 时,可以使用数组展开语法实现类似的结果。即调用call方法
  1. 案例
// 1.普通用法
var a = {
  name: "cherry",
  fn: function(a, b) {
    console.log(a + b);
  }
};
var b = a.fn;
b.apply(a, [1,2])  // 3

// 2.用 apply 将数组各项添加到另一个数组
const array = ['a', 'b'];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

// 3.找出数组中最大/小的数字
const numbers = [5, 6, 2, 3, 7];

// 使用 Math.min/Math.max 以及 apply 函数时的代码
let max = Math.max.apply(null, numbers); // 基本等同于 Math.max(number[0], ...) 或 Math.max(5, 6, ..)

let min = Math.min.apply(null, numbers);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 3.bind

  1. 语法、参数、返回值
function.bind(thisArg[, arg1[, arg2[, ...]]])

// thisArg:调用绑定函数时作为 this 参数传递给目标函数的值。如果使用new运算符构造绑定函数,则忽略该值。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArg是null或undefined,执行作用域的 this 将被视为新函数的 thisArg
// arg1, arg2, ...:当目标函数被调用时,被预置入绑定函数的参数列表中的参数

// 返回值:返回一个原函数的拷贝,并拥有指定的 this 值和初始参数
1
2
3
4
5
6
  1. 案例
this.x = 9;    // 在浏览器中,this 指向全局的 "window" 对象
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();
// 返回 9 - 因为函数是在全局作用域中调用的

// 创建一个新函数,把 'this' 绑定到 module 对象
// 新手可能会将全局变量 x 与 module 的属性 x 混淆
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 总结:

  • 第一个参数都是this要指向的对象,如果没有这个参数或者参数为undefined、null。则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数。bind可以分多次传入
  • bind是返回绑定this之后的函数,apply、call则是立即执行
最近更新时间: 3/1/2023, 6:24:06 AM
강남역 4번 출구
Plastic / Fallin` Dild