work
This commit is contained in:
parent
057783d216
commit
3f5f2cac8b
324 changed files with 669 additions and 286 deletions
|
@ -281,83 +281,6 @@ Any other operation like assignment `hi = user.hi` discards the reference type a
|
|||
So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj[method]()` syntax (they do the same here).
|
||||
|
||||
|
||||
## Explicit "this" with "call/apply" [#call-apply]
|
||||
|
||||
The value of `this` does not have to come from the aforementioned rules.
|
||||
|
||||
We can explicitly set it to any object using `func.call`.
|
||||
|
||||
The syntax is:
|
||||
|
||||
```js
|
||||
func.call(context, arg1, arg2, ...)
|
||||
```
|
||||
|
||||
For instance:
|
||||
|
||||
```js run
|
||||
function sayHi() {
|
||||
alert(this.name);
|
||||
}
|
||||
|
||||
let user = { name: "John" };
|
||||
let admin = { name: "Admin" };
|
||||
|
||||
// use call to pass different objects as "this"
|
||||
sayHi.call( user ); // John
|
||||
sayHi.call( admin ); // Admin
|
||||
```
|
||||
|
||||
The first parameter of `call` is the intended value of `"this"`, the latter are arguments.
|
||||
|
||||
So `sayHi.call(admin)` runs the function `sayHi` with `this = admin`, hence `this.name` in it becomes `"Admin"`.
|
||||
|
||||
These calls are roughly equivalent:
|
||||
```js
|
||||
func(1, 2, 3);
|
||||
func.call(obj, 1, 2, 3)
|
||||
```
|
||||
|
||||
They both call `func` with arguments `1`, `2` and `3`. The only difference is that `call` also sets `"this"`.
|
||||
|
||||
The method `func.call` is used when we'd like to use a function in the context of different objects, but do not want to actually assign it to them. We'll see more examples of it soon.
|
||||
|
||||
### "func.apply"
|
||||
|
||||
There's also a similar method `func.apply`:
|
||||
|
||||
```js
|
||||
func.apply(context, args)
|
||||
```
|
||||
|
||||
It does the same as `call`: executes the function providing `context` as `this`, but where `call` awaits a list of arguments, `apply` awaits an array.
|
||||
|
||||
These two calls do the same:
|
||||
|
||||
```js
|
||||
func.call(obj, 1, 2, 3);
|
||||
func.apply(obj, [1, 2, 3]);
|
||||
```
|
||||
|
||||
In old times `apply` was more powerful, because it allows to create the array of arguments dynamically. Their number is not hardcoded at code-write time.
|
||||
|
||||
But in the modern language, we have the spread operator `'...'` and can use it to convert an array into a list of for `call`, so these two are equal:
|
||||
|
||||
```js
|
||||
let args = [1, 2, 3];
|
||||
|
||||
func.call(obj, ...args);
|
||||
func.apply(obj, args);
|
||||
```
|
||||
|
||||
Nowadays the use of `apply` or `call` is mainly a metter of personal preference. But `apply` is somewhat better optimized in engines than the call + spread combination, because it exists longer. So it would execute a little bit faster.
|
||||
|
||||
## Binding "this" with "bind"
|
||||
|
||||
There's still a way to bind "this" to a function.
|
||||
|
||||
[todo] migrate bind here????
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue