Maison > Questions et réponses > le corps du texte
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) ?
给我你的怀抱2017-06-12 09:32:07
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 :
var jawil = {
name: "jawil",
sayHello: function (age) {
console.log("hello, i am ", this.name + " " + age + " years old");
}
};
var lulin = {
name: "lulin",
};
jawil.sayHello(24);
// hello, i am jawil 24 years old
Ensuite, regardez le résultat après avoir utilisé call
:
jawil.sayHello.call(lulin, 24);// hello, i am lulin 24 years old
Laissez-moi répondre à vos questions à base de marrons :
consiste à simuler l'implémentation de
call
的实现,请问为什么要push一个字符串,下面再用eva
l?直接传入arguments[i]
,然后下面用context.fn(args)
Pourquoi avez-vous besoin de pousser une chaîne et d'utilisereva
l ensuite ? Transmettez directementarguments[i]
, puis utilisezcontext.fn(args)
pourquoi pas ?
Tout d'abord, vous devez comprendre la relation entre les fonctions simulées ci-dessus et les variables dans le châtaignier :
context => lulin
context.fn => jawil.sayHello
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çoncontext
得到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 lulin.sayHello(arg1,arg2,arg3,arg4)
, car lulin.sayHello
doit réorganiser les paramètres, vous ne pouvez pas lulin.sayHello(arg1,arg2,arg3,arg4)
这样的,因为lulin.sayHello
要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用eval
en obtenir un Exécutez la fonction une fois avec les paramètres
enregistrez les paramètres ensemble et exécutez-la une fois 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 lulin.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.
Jetons un bref aperçu de laLa fonctionfonction
définition et utilisation
eval() peut calculer une chaîne et y exécuter le code JavaScript. eval(string)
Grammaire :🎜 🎜🎜chaîne requise. Chaîne à évaluer qui contient une expression JavaScript à évaluer ou une instruction à exécuter. Cette méthode n'accepte qu'une chaîne brute comme paramètre, si le paramètre de chaîne n'est pas une chaîne brute, alors la méthode retournera inchangée. Par conséquent, veuillez ne pas transmettre d'objets String comme arguments à la fonction eval(). 🎜
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>
.
eval('function Test(a,b,c,d){console.log(a,b,c,d)};
Test(1,2,3,4)')
C'est équivalent à ça
<script>
function Test(a,b,c,d){
console.log(a,b,c,d)
};
Test(1,2,3,4)
</script>
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 :
Function.prototype.call2 = function(context) {
context.fn = this;
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
console.log(args)
var star = 'context.fn(' + args + ')'
console.log(star)
eval('context.fn(' + args + ')');
delete context.fn;
}
var jawil = {
name: "jawil",
sayHello: function(age) {
console.log("hello, i am ", this.name + " " + age + " years old");
}
};
var lulin = {
name: "lulin",
};
jawil.sayHello.call2(lulin, 24, 25);
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< /code>
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.
曾经蜡笔没有小新2017-06-12 09:32:07
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.
淡淡烟草味2017-06-12 09:32:07
Parce que les arguments[0] sont le contexte
N'avez-vous pas vu que la variable de boucle commence à 1 ?