Decorators and forwarding, call apply
JavaScript Decorators and Forwarding, Call / Apply (JavaScript装饰和转发、调用/应用)
In JavaScript, you can work with functions with excellent flexibility. You can pass them around, use them as objects. In this chapter, we are going to show you how to decorate them and forward calls between them. (在JavaScript中,您可以灵活地使用函数。您可以传递它们,将其用作对象。在本章中,我们将向您展示如何装饰它们并转接它们之间的呼叫。)
Using “func.call” for the Context
Using “func.call” for the Context (将“func.call”用于上下文)
You can use a unique built-in function method func.call(context, …args), allowing to invoke a function explicitly setting this. (您可以使用唯一的内置函数方法func.call (context,… args) ,允许调用显式设置此参数的函数。)
The syntax is as follows:
func.call(context, arg1, arg2, ...)
The syntax given above runs the func providing the first argument like this, and the following as the arguments. (上面给出的语法运行提供第一个参数的函数,如下所示,作为参数。)
Let’s check out the following calls :
func(1, 2, 3);
func.call(obj, 1, 2, 3)
Both of them call the func with 1, 2 and 3 arguments. The main difference is that func.call sets this to obj. (他们都用1、2和3个参数来称呼函数。主要区别在于func.call将此设置为obj。)
Here is an example:
function welcomeSite() {
console.log(this.name);
}
let site = {
name: "w3cdoc"
};
let book = {
name: "Javascript"
};
// use call to pass different objects as "this"
welcomeSite.call(site); // this = w3cdoc
welcomeSite.call(book); // this = Javascript
Here call is used to call welcome with a particular context an phrase, like this:
function welcome(message) {
console.log(message + ' to ' + this.siteName);
}
let site = {
siteName: "w3cdoc"
};
// site becomes this, and "Welcome" becomes the first argument
welcome.call(site, "Welcome"); //Welcome to w3cdoc
Going Multi-argument with “func.apply”
Going Multi-argument with “func.apply” (使用“func.apply”进行多参数)
It is also possible to use another built-in method func.apply. The syntax is as follows:
func.apply(context, args)
The syntax above runs the func setting this=context and using an array-like object args as the list of arguments. (上面的语法运行func设置this = context ,并使用类似数组的对象args作为参数列表。)
For example, the following calls are nearly similar:
func(1, 2, 3);
func.apply(context, [1, 2, 3])
Both of them run func giving it the following arguments: 1,2,3. Note that apply may also set this=context.
Let’s observe the following case:
function welcome(message) {
console.log(` ${message} to ${this.siteName}`);
}
let site = {
siteName: "w3cdoc"
};
let messageData = ['Welcome']; // become message
// site becomes this, messageData is passed as a argument (message)
welcome.apply(site, messageData); //Welcome to w3cdoc (this=site)
Now, let’s see what the difference between call and apply is: the call expects a list of arguments while apply takes an array-like object with them.
The spread operator … can pass an array as a list of arguments. In case of using it with call, it is possible to achieve nearly the same as apply. (Spread运算符…可以将数组作为参数列表传递。如果将其与调用一起使用,则可以实现几乎与应用相同的目标。)
The following two calls are almost the same:
let args = [1, 2, 3];
func.call(context, ...args); // pass an array as list with spread operator
func.apply(context, args); // is same as using apply
The differences between them are minor. Here they are:
The spread operator allows passing iterable args like the list to call. The apply may accept merely array-like args. (Spread运算符允许传递可迭代的参数,如要调用的列表。 Apply可以仅接受类似数组的参数。)
Among the essential uses of the apply, we can mention its ability to pass the call to another function, as follows:
let wrapper = function () {
return anotherFunction.apply(this, arguments);
};
It is known as call forwarding. The wrapper passes all that it receives: the context this, as well as arguments to anotherFunction returning its result.
Borrowing a method [#method-borrowing]
Borrowing a method [#method-borrowing]
Now it’s necessary to make another improvement in the hashing function. It looks like this:
function hash(args) {
return args[0] + ',' + args[1];
}
In this case, it can operate only with two arguments. The arr.join method is used to make it work with any number of args, as follows:
function hash(args) {
return args.join();
}
But don’t get surprised if it doesn’t work. The reason is that the hash(arguments) is called, and the arguments object is iterable and array-like but not a real array. (但如果它不起作用,不要感到惊讶。原因是哈希(参数)被调用,并且参数对象是可迭代且类似于数组,但不是实数组。)
In the event of calling join on it, will fail:
function hash() {
console.log(arguments.join()); // Error: arguments.join is not a function
}
hash(1, 2);
You can apply to a simple and efficient way of using array join. Here it is:
function hash() {
console.log([].join.call(arguments)); // 1,2
}
hash(1, 2);
It is known as method borrowing. (它被称为方法借用。)
So, you borrow a join method from a regular array [].join using [].join.call to run it in the context of the arguments. It works as the arr.join(glue) native method algorithm is quite simple.