Cet article partagera avec vous une question d'entretien classique pour voir comment rendre "a==1&&a==2&&a==3" vrai ? Grâce à cette question d'entretien, j'ai appris les points de connaissances qu'elle contient. J'espère qu'elle sera utile à tout le monde !
if (a == 1 && a == 2 && a == 3) { console.log('Win') }
Comment saisir le code s'il est exécuté et imprimer avec succès Win
sur la console ?Win
?
看到题目的第一眼,我是蒙蔽的.怎么可能会有如此矛盾的情况发生呢?就相当于一个人怎么可能即是小孩,又是成年人,还是老年人呢?
冷静下来,发现一些端倪。
它没说让a同时等于1 2 3。
而且js是单线程运行的。 即使它们写在了一行,那也是从左到右执行的. 所以它们从时空上面就不是同一时期的东西。
既然不是同一时期的东西,那么一个人当然可以是可以成为小孩子,之后成为过成年人,然后变成老年人了。
回到题目,那么我想要让这个条件成立,就需要获取一次a的同时,让它自增1。
第一种方法,利用判断过程中的[隐式转换]的toString
方法。在我的另外一篇为什么[] == ![]结果为true?中详细阐述过。
const a = { _a: 0, toString: function() { return ++a._a } }
运行一次,就给_a加1,然后返回.
因为toString是Object.prototype
上面默认的方法,所以这个办法相当于把正常的隐式转换中toString
方法给拦截了。
涉及原型和原型链的知识点
问题是可以解决了。
评论区的有掘友说让 a = true 也可以解决的。确实很有误导性。其实是混淆了隐式转化的优先级。简单来说,隐式转化是由两部分组成:转化的规则 + 触发转化的条件。if
包着的里面整体触发了Boolean()
的转化规则,==
又字符串在右侧触发toString()
的转化规则。
回到这题,==
的右边是数字,JS运行线路是从左到右的。所以,这个时候触发的是Number()
的规则,把左侧的true
转化为1
之后,两边类型一致之后,那自然不会再触发什么规则了,此时已经不构成隐式转化。所以说1 == 1 && 1 == 2 && 1 == 3
是不成立的。
现在记住了,也比面试过程中的时候再来记好
现在将题目简单修改一下,将双等变成三个等怎么办?
大家都知道===
的话是先判断类型,再判断值。这里的toString
已经默认把对象转化为字符串了.使用toStirng
Il ne dit pas que a soit égal à 1 2 3 en même temps.
Comme ils ne sont pas de la même époque, alors bien sûr une personne peut devenir un enfant, puis un adulte, puis une personne âgée.Et js s'exécute dans un seul thread. Même s’ils sont écrits sur une seule ligne, ils sont exécutés de gauche à droite. Ils ne sont donc pas de la même époque dans le temps et dans l’espace.
2.1 toString
La première méthode consiste à utiliser [caché] dans le processus de jugement . Méthode de conversion toString
]. Dans mon autre article Pourquoi[ ] = = ![] Le résultat est vrai ? expliqué en détail.
Object.defineProperties(window, { _a: { value: 0, writable: true }, a: { get: function() { return ++_a } } })
Object.prototype
, cette méthode est donc équivalente à une conversion implicite normale toString est interceptée. 🎜🎜🎜Points de connaissances concernant les prototypes et les chaînes de prototypes🎜🎜🎜Le problème peut être résolu. 🎜🎜Certains amis dans la zone de commentaires ont dit que définir a = true peut également résoudre le problème. Très trompeur en effet. En fait, cela confond la priorité de la conversion implicite. En termes simples, la conversion implicite se compose de deux parties : 🎜Règles de conversion + conditions qui déclenchent la conversion🎜. Le package <code>if
déclenche la règle de conversion de Boolean()
dans son ensemble, et la chaîne déclenche toString(() sur le côté droit de <code>==
). 🎜🎜Retour à cette question, le côté droit de ==
est un nombre et la ligne courante JS est de gauche à droite. Par conséquent, ce qui est déclenché à ce moment est la règle de Number()
. Après avoir converti le true
à gauche en 1
, les types de. les deux côtés seront identiques🎜, alors naturellement plus de règles ne seront déclenchées, et cela ne constitue plus une conversion implicite. Donc 1 == 1 && 1 == 2 && 1 == 3
n'est pas vrai. 🎜🎜🎜Maintenant que je l'ai mémorisée, c'est mieux que de la mémoriser pendant l'entretien🎜🎜🎜Maintenant, je modifie simplement la question et la change du double au triple etc. Que dois-je faire ? 🎜🎜Tout le monde sait que ===
détermine d'abord le type puis la valeur. Le toString
ici a converti l'objet en chaîne par défaut. Si vous utilisez toStirng
, le résultat ne sera pas vrai 🎜🎜🎜2.2 DefineProperties🎜🎜🎜Utilisez celui de l'objet. méthode d'interception de données :🎜rrreee🎜impliquant du contenu lié aux accesseurs d'objets🎜🎜🎜Je me demande si cela vous rappelle la montre ou les instructions calculées dans Vue ? 🎜🎜🎜🎜3.Résumé🎜🎜🎜Que vous puissiez répondre à cette question d'entretien n'a aucune signification. Mais il est très intéressant de comprendre les points de connaissance contenus dans cette question d'entretien. 🎜🎜Des conversions de types implicites aux prototypes et chaînes de prototypes, et enfin aux propriétés de droits d'accès des objets. Si vous souhaitez continuer à étendre, le principe d'implémentation de la liaison bidirectionnelle de Vue, l'implémentation de static en classe, etc. 🎜🎜C'est pourquoi on dit qu'il est nécessaire de construire un système de connaissances frontal qui peut s'étendre d'un point de connaissance à d'autres points de connaissances connexes. 🎜🎜【Apprentissage recommandé : 🎜Tutoriel avancé javascript🎜】🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!