Function.prototype.call2 = function(context) {
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
eval('context.fn(' + args +')');
delete context.fn;
}
Il s'agit de simuler l'implémentation de call. Pourquoi avez-vous besoin de pousser une chaîne puis d'utiliser eval ensuite ? Pourquoi ne pas transmettre directement arguments[i] puis utiliser context.fn(args) ?
Ici, je pense que vous avez également compris les instructions du
call
的原理,这里我简要还是说明一下原理,我也是参考JavaScript
guide faisant autorité et que vous l'avez ensuite implémenté avec du code.Tout d'abord, jetons un coup d'œil à la syntaxe et à la définition de

call
, à partir de la version chinoise de la spécification ECMAScript :Donnons un exemple simple :
Ensuite, regardez le résultat après avoir utilisé
call
:Laissez-moi répondre à vos questions à base de marrons :
Tout d'abord, vous devez comprendre la relation entre les fonctions simulées ci-dessus et les variables dans le châtaignier :
Remarquez cette étape, on vient de mettre
jawil.sayHello
的引用地址给了lulin.sayHello
Il s'avère
jawil.sayHello.call(context,arg1,arg2,arg3,arg4)
Cull à votre façon
context
得到args=[arg1,arg2,arg3,arg4]
Ensuite, exécutez
lulin.sayHello([arg1,arg2,arg3,arg4])
Haha, c'est très déroutant, n'est-ce pas ? Cela a l'air bien, mais en fait, il s'avère qu'il y avait quatre paramètres, et maintenant ils sont regroupés dans un tableau et deviennent un seul paramètre de tableau. C'est là que réside le problème.Alors, comment résoudre ce problème ? L'idée est la même que ci-dessus, mettre tous les paramètres dans une chaîne, puis utiliser
eval
pour exécuter.L'effet que nous voulons est
, oululin.sayHello(arg1,arg2,arg3,arg4)
, carlulin.sayHello
doit réorganiser les paramètres, vous ne pouvez paslulin.sayHello(arg1,arg2,arg3,arg4)
这样的,因为lulin.sayHello
要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用eval
en obtenir un Exécutez la fonction une fois avec les paramètresenregistrez les paramètres ensemble et exécutez-la une fois
pour exécuter,lulin.sayHello([arg1,arg2,arg3,arg4])
,也不是lulin.sayHello(arg1)
,lulin.sayHello(arg2)
La seule façon qui me vient à l'esprit est de mettre tous les paramètres dans une chaîne, puis d'utiliser.
Similaire à ceci : "lulin.sayHello(arg1,arg2,arg3,arg4)" C'est comme ça que nous voulons, pas, ni
La fonctionlulin.sayHello(arg1)
,lulin.sayHello (arg2)
...eval
Qu'est-ce qu'eval ? Laissez-moi vous l'expliquer brièvement ici. Je ferai comme si vous ne saviez rien.
eval() peut calculer une chaîne et y exécuter le code JavaScript.
eval(string)
Pour faire simple, il utilise le moteur d'analyse JavaScript pour analyser le contenu de ce groupe de chaînes. Disons-le de cette façon, vous pouvez le comprendre de cette façon, vous mettez la balise
eval
看成是<script>
.C'est équivalent à ça
D'accord, regardons à nouveau le code ci-dessus. En fait, il y a encore des pièges. Jetons un coup d'œil à l'intuition modale. Ci-dessous le code de débogage complet :
Regardez le résultat d'args :

["arguments[1]", "arguments[2]"]
Regardez ensuite le résultat de 'context.fn(' + args + ')' :

"context.fn(arguments[1],arguments[2])"N'est-ce pas un peu déroutant
En fait, il s'agit ici d'une conversion implicite.
'jawil'+[1,2]+[3,4]+3
équivaut à quoi ?Égal à
"jawil1,23,43"
'jawil'+[1,2]+[3,4]+3
等于多少?等于
"jawil1,23,43"
其实这个相当于
'jawil'+[1,2].toString()+[3,4].toString()+3
En fait, cela équivaut à'jawil'+[1,2].toString()+[3,4].toString( )+3
L'espace est limité, pour plus de conversions implicites, veuillez vous référer à mon article : From ++[[]][+[]]+[+[]]==10 ? JS
En parlant de cela, j'ai dit toutes les choses essentielles. Vous pouvez le comprendre vous-même. L'auteur original a probablement consulté d'autres lors de l'écriture de ceci. Il y a beaucoup de choses qui n'ont pas été expliquées clairement, je suppose, en raison de l'espace limité, je viens de le mentionner. d'un seul coup. Cela semble être un paragraphe très court. Le code contient en fait beaucoup de points de connaissance.
args est un tableau,
context.fn(args)
n'a qu'un seul paramètre. Dans des circonstances normales, vous pouvez utiliser apply pour convertir le tableau en paramètres, mais ici, pour simuler un appel, utiliser apply n'a aucun sens. Il utilise donc le toString() du tableau pour déplacer des paramètres autres que le contexte vers context.fn.Parce que les arguments[0] sont le contexte
N'avez-vous pas vu que la variable de boucle commence à 1 ?