浅谈call、apply和bind

博客主要介绍了JavaScript中call()、apply()、bind()方法的定义。call()用指定this值和单独参数调用函数,apply()用数组参数调用,bind()创建新函数并指定this值。还分析了三者相同点是可指定this值和提供参数,不同点在于参数形式和是否创建新函数,且可用call()/apply()实现bind()。

定义

call() :

使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

apply() :

调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

bind():

创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

分析:

先上栗子

var module = {
  x: 42,
  getSite: function(y, z) {
	console.log(this);
    return `${this.x},${y},${z}`;
  }
};

var getSiteCopy = module.getSite;

console.log(getSiteCopy(142, 21)); // undefined,142,21

console.log(getSiteCopy.call(module, 142, 21)); // 42,142,21

console.log(getSiteCopy.apply(module, [142, 21])); // 42,142,21

var getSiteBind = getSiteCopy.bind(module, 142, 21);
console.log(getSiteBind ()); // 42,142,21

运行截图

在这里插入图片描述
接下来针对这个栗子进行分析

相同点:

call()、apply()、bind()三者,都是可以对一个函数指定this值,并且可以提供参数。

console.log(getSiteCopy(142, 21)) // undefined,142,21

因为这里getSiteCopy(142, 21)的执行环境是window,window中获取不到this.x,所以结果为undefined。

console.log(getSiteCopy.call(module, 142, 21)); // 42,142,21
console.log(getSiteCopy.apply(module, [142, 21])); // 42,142,21
var getSiteBind = getSiteCopy.bind(module, 142, 21);
console.log(getSiteBind ()); // 42,142,21

但是使用了call()、apply()、bind()就能顺利取到this.x,因为它们将this指向module了。

不同点:

call():

参数的形式是单独给出

console.log(getSiteCopy.call(module, 142, 21));

apply():
参数的形式是一个数组(或类数组对象)

console.log(getSiteCopy.apply(module, [142, 21]));

bind():
创建一个新的函数

var getSiteBind = getSiteCopy.bind(module, 142, 21);
console.log(getSiteBind ()); // 42,142,21

在了解bind()和call()/apply()的区别之后,其实我们可以使用call()/apply()来实现bind()。
详见: 使用apply(),实现bind()




ps:转载请注明出处
### Function.prototype.call、Function.prototype.apply Function.prototype.bind 的区别 在 JavaScript 中,`call`、`apply` `bind` 是函数对象的原型方法,它们都用于控制函数执行时的 `this` 上下文。尽管它们的功能相似,但在使用方式行为上存在关键差异。 #### 1. Function.prototype.call `call` 方法允许调用一个函数,并指定其运行时的 `this` 值以及一系列参数列表。这些参数是以逗号分隔的形式传入的。 例如: ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: 'Alice' }; greet.call(person, 'Hello', '!'); // 输出 "Hello, Alice!" ``` 这里 `greet` 函数通过 `call` 被调用,`this` 指向了 `person` 对象,并且传递了 `'Hello'` `'!'` 作为参数[^4]。 #### 2. Function.prototype.apply `apply` 方法与 `call` 类似,也用于调用函数并设置 `this` 值,但它的参数是一个数组(或类数组对象)。这意味着你可以将参数以数组形式传递给 `apply`。 例如: ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: 'Alice' }; const args = ['Hello', '!']; greet.apply(person, args); // 输出 "Hello, Alice!" ``` 在这个例子中,`args` 数组包含了所有要传递给 `greet` 函数的参数[^4]。 #### 3. Function.prototype.bind 不同于 `call` `apply`,`bind` 不会立即调用函数,而是创建一个新的函数实例,这个新函数的 `this` 值被永久绑定到提供的值,并且可以预设一些参数。 例如: ```javascript function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: 'Alice' }; const boundGreet = greet.bind(person, 'Hello'); boundGreet('!'); // 输出 "Hello, Alice!" ``` 这里 `greet` 函数通过 `bind` 创建了一个新的函数 `boundGreet`,其中 `this` 被绑定到了 `person`,并且 `'Hello'` 被预设为第一个参数。 #### 总结 - **`call`**:调用函数并指定 `this`,参数以逗号分隔。 - **`apply`**:调用函数并指定 `this`,参数以数组形式提供。 - **`bind`**:返回一个新函数,该函数的 `this` 被绑定,并且可以预设参数。 每种方法都有其适用场景。当你需要立即调用函数并且知道参数时,可以选择 `call` 或 `apply`;而当你想要创建一个具有固定上下文的新函数时,则应选择 `bind`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值