JavaScript函数之call、apply以及bind方法案例详解
本文将详细介绍JavaScript中的函数三大方法:call、apply、bind。它们用于改变函数内部this指向的对象,并且可以传递一些参数,方便我们灵活地调用函数。在本文中,我们将一步一步的讲解这三个函数的使用方法,并通过多个示例来详细说明其使用场景与细节问题。
call() 方法
call()
方法被调用时,使用指定的 this
值和单独给出的一个或多个参数来调用一个函数。举个例子:
function sayHello() {
console.log(`Hello, ${this.name}!`);
}
let user = { name: 'Jane Doe' };
sayHello.call(user); // 输出 "Hello, Jane Doe!"
在这个例子中,call()
方法将 sayHello()
函数的 this
指针设置为指定的 user
对象。这样,我们就能够在 sayHello()
函数中访问 user
对象中的属性。
此外,call()
方法除了可以改变函数内部的 this
,还可以将参数按逗号分隔的形式依次传给函数,如下所示:
function sayMessage(message) {
console.log(`${this.name} say: ${message}`);
}
let user = { name: 'Jane Doe' };
sayMessage.call(user, 'Hello, World!'); // 输出 "Jane Doe say: Hello, World!"
在这个例子中,call()
方法还将字符串 "Hello, World!"
作为参数传递给了 sayMessage()
函数,用作信息字符串的内容。
apply() 方法
apply()
方法与 call()
方法的作用类似,不同之处仅在于 apply()
方法传递参数的形式。 举个例子:
function sayMessage(message) {
console.log(`${this.name} say: ${message}`);
}
let user = { name: 'Jane Doe' };
let messages = ['Hello,', 'World!'];
sayMessage.apply(user, messages); // 输出 "Jane Doe say: Hello, World!"
在这个例子中,apply()
方法接收两个参数,第一个参数是需要绑定给 this
的对象,第二个参数则是一个数组,它包含了需要传递给该函数的参数(在本例中,数组 messages
包含两个字符串内容)。
注意:在 ES6
之后,我们可以用展开操作符来替代 apply 方法:
sayMessage.bind(user, ...messages)();
bind() 方法
bind()
方法同样是用来改变函数内部的 this
,不同之处在于 bind()
方法返回的是一个新的函数。这个新的函数的 this
值被永久绑定到了传递给 bind()
方法的第一个参数(这个参数在 call() and apply()
中扮演的角色一样)。 举个例子:
var fullName = 'John Doe';
var person = {
fullName: 'Jane Doe',
sayFullName: function() {
console.log(`Full Name: ${this.fullName}`);
}
};
var sayFullName = person.sayFullName.bind(person);
sayFullName(); // 输出 Full Name: Jane Doe
sayFullName.call({ fullName: 'sadhu' }); // 输出 Full Name: Jane Doe
在这个例子中,person.sayFullName()
方法的 this
指针将被绑定到 person
对象中,并返回一个新的函数 sayFullName
。当我们调用 sayFullName()
时,输出的 Full Name:
信息中将包含 person.fullName
属性中存储的值,而不是全局中定义的 fullName
变量中存储的值。
值得注意的是,当使用 bind()
方法时,还可以在新函数被调用时向旧函数的参数传递一些默认值,如下所示:
function multiply(factor1, factor2) {
return factor1 * factor2;
}
let double = multiply.bind(null, 2);
console.log(double(3)); // 6
console.log(double(4)); // 8
在这个例子中,我们通过调用 multiply.bind(null, 2)
方法创建了一个新函数 double()
,它被永久性的绑定到 multiply()
方法中的第一个参数为 2。这样,当我们调用 double()
方法并传递一个整数参数时,返回值将是该参数和常量数字 2 的积。
示例一:更改Array原型链方法forEach
我们通常可以使用 array
的 forEach
方法快速循环数组进行遍历,但是有时候快速单位任务执行完可能会引起一些问题。如果我们想规避这些问题并且还想使用 forEach
,你可以重写 forEach
方法来更改 this
上下文。下面是示例代码:
let array = ['a', 'b', 'c'];
Array.prototype.forEachOriginal = Array.prototype.forEach;
Array.prototype.forEach = function(callback, thisObj) {
thisObj = thisObj || this;
return Array.prototype.forEachOriginal.call(this, callback.bind(thisObj));
};
let obj = {
foo: 'bar'
};
array.forEach(function(e) {
console.log(`${e} and ${this.foo}`);
}, obj);
在这个示例中,重写了 array 的 forEach
方法,将 callback
中的 this
上下文传递给第二个参数。我们将实例 this
对象传递给第二个参数的默认值,以确保始终使用作用于 array
的上下文。现在我们可以有更好的方式来使用 forEach
,并且避免了不必要的问题。
示例二:使用 apply
调用自定义构造函数
有时候,我们想要非常灵活地通过定义参数数组来调用 Javascript 中的函数。这时,apply()
和 call()
方法就很有用了。我们将它们运用到我们自己的构造函数中,并像下面这样使用它们:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.greeting = function(message) {
console.log(`${message}, ${this.firstName} ${this.lastName}`);
};
let messages = ['Hello'];
let person = new Person('John', 'Doe');
person.greeting.apply(person, messages); // 输出:Hello, John Doe
在这个示例中,我们使用 apply
方法调用了 person.greeting
函数并传递了两个参数:person
实例和数组 messages
。使用 apply 方法来调用函数和 call
方法类似,区别只在于参数的传递形式不同。
注:本文的所有JS代码都是在node.js的环境下编写并运行的,如果你使用浏览器来执行其中的脚本,请打开浏览器中的开发者工具(F12),在控制台(console)中运行。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript函数之call、apply以及bind方法案例详解 - Python技术站