javascript - Implémentation d'une méthode d'appel en js
PHP中文网
PHP中文网 2017-06-12 09:30:07
0
3
896
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) ?

PHP中文网
PHP中文网

认证高级PHP讲师

répondre à tous(3)
给我你的怀抱

Ici, je pense que vous avez également compris les instructions du call的原理,这里我简要还是说明一下原理,我也是参考JavaScriptguide 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一个字符串,下面再用eval?直接传入arguments[i],然后下面用context.fn(args) Pourquoi avez-vous besoin de pousser une chaîne et d'utiliser eval ensuite ? Transmettez directement arguments[i], puis utilisez context.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要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用evalen obtenir un Exécutez la fonction une fois avec les paramètres

, ou

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

pour exécuter,

.

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 la

fonction

définition et utilisation
La fonction


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()+3En 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 ?

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal