Note : J'utiliserai apply
au lieu de call
dans ma réponse juste parce que la formulation/lecture est un peu moins confuse, mais la même réponse s'applique à call
.
Vous pouvez imaginer apply
ressemble à quelque chose comme ça :
Function.prototype.apply = function apply(context, rest) {
// `this` in here is the function object on which we call `apply` as a method
// we then invoke whatever is bound to `this` (it should be the function that was "applied")
// and change its context and pass the rest of the arguments
// Note: I'm using `call` since we don't have access to native function code that can call a function with an overwritten context
this.call(context, ...rest)
}
Lorsque vous appelez le apply
(ou toute autre fonction d'ailleurs) en tant que méthode sur un objet fonction ( les fonctions sont des objets de première classe ), this
à l'intérieur de celui-ci est lié à la fonction (objet) sur laquelle vous avez appelé apply
(il s'agit d'une des règles sur la façon dont le contexte est lié en JS lorsqu'une fonction est appelée en tant que méthode d'un objet)
Function.prototype.apply = function apply(context, rest) {
this.call(context, ...rest)
// `this` is the function that `call` invokes
// in the example bellow, `this` is `console.log`
// so this function will do `console.log.call(console, 'example')`
}
console.log.apply(console, ['example'])
// ^^^^^^^^ console.log is the context because we are calling `apply` on it, with the dot (.) notation
Cependant, lorsque vous stockez le apply
dans une variable et l'invoquer ensuite, alors la règle pour la fonction this
contraignant est d'être undefined
(en mode strict ou en mode global window
sinon) et il n'y a donc pas de fonction à appeler sous le capot.
Function.prototype.apply = function apply(context, rest) {
this.call(context, ...rest)
// using the example bellow
// `this` is `undefined` now because `apply` was called like a regular function, not a method
// which means the code bellow does `undefined.call(console, 'example')`
}
// calling a function as a normal function (not a method via the dot notation), makes `this` be `undefined`
// therefore `apply` doesn't have a function which to call with an overwritten context
let apply = console.log.apply;
apply(console, ['example']) // error, `this.call is not a function`