JS中if(a ==1 a== 2 a==3)判定为true的另类思考

news/2024/7/7 20:47:02

故事来源

前阵子同事偶然在Q上给我发了一段文字

Is it ever possible that (a==1&&a==2&&a==3) could evaluate to true, in JavaScript?

作为一个从事过.C#代码的我来说,第一反应就想起了运算符重载(原谅我如此粗暴)。其实这个问题的答案可以用valueOf解决,网上也有各路神仙形形色色的解决办法。不过我还是思考了下如何通过运算符重载实现此问题。

解决方案

问题非常简单,我发现一个babel的plugin,可以间接实现运算符重载。https://github.com/gzz2000/babel-plugin-operator

使用方式

  • 手写如下代码,按照上面github工程的说明操作就可以了,非常简单。
'bpo enable';
class Point {

    operatorAdd = (b) => {
	    const a = this;
	    return new Point(a.x + b.x, a.y + b.y);
    }

    operatorMul = (b) => {
	    const a = this;
	    return new Point(a.x * b, a.y * b);
    }

    operatorEqual = (b) => {
        return true;
    }
};

let a = new Point();

if (a==1&&a==2&&a==3) {
    console.log('true');
}
复制代码
  • 执行结果

  • 来看下经过babel转换的dist/index.js内容是啥(截取部分)

          var _Op = function () {
              'bpo disable';
    
              return {
                  add: function add(a, b) {
                      if (a.operatorAdd) return a.operatorAdd(b);else return a + b;
                  },
                  sub: function sub(a, b) {
                      if (a.operatorSub) return a.operatorSub(b);else return a - b;
                  },
                  equal: function equal(a, b) {
                      if (a.operatorEqual) return a.operatorEqual(b);else if (a.operatorNotEqual) return !a.operatorNotEqual(b);else if (b.operatorEqual) return b.operatorEqual(a);else if (b.operatorNotEqual) return !b.operatorNotEqual(a);else return a == b;
                  },
                  notEqual: function notEqual(a, b) {
                      if (a.operatorNotEqual) return a.operatorNotEqual(b);else if (a.operatorEqual) return !a.operatorEqual(b);else if (b.operatorNotEqual) return b.operatorNotEqual(a);else if (b.operatorEqual) return !b.operatorEqual(a);else return a != b;
                  }
              };
          }();
    
          var Point = function Point() {
              var _this = this;
    
              _classCallCheck(this, Point);
    
              this.operatorAdd = function (b) {
                  var a = _this;
                  return new Point(_Op.add(a.x, b.x), _Op.add(a.y, b.y));
              };
    
              this.operatorMul = function (b) {
                  var a = _this;
                  return new Point(_Op.mul(a.x, b), _Op.mul(a.y, b));
              };
    
              this.operatorEqual = function (b) {
                  return true;
              };
          };
    
          ;
    
          var a = new Point();
    
          if (_Op.equal(a, 1) && _Op.equal(a, 2) && _Op.equal(a, 3)) {
              console.log('true');
          }
    复制代码

问题思考

原理其实很简单,熟悉的babel的童鞋一看就理解为何了。其实就是对源码进行了转换等操作。感兴趣对可以看看https://github.com/thejameskyle/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md#toc-asts这篇文章,是介绍如何编写plugin的。在.net内对象之间的判定操作时运算符重载是非常常见的。

转载于:https://juejin.im/post/5a6e08fd51882573421723fb


http://www.niftyadmin.cn/n/3778346.html

相关文章

[树链剖分]JZOJ 5914 盟主的忧虑

Description 江湖由 N 个门派(2≤N≤100,000,编号从 1 到 N)组成,这些门派之间有 N-1 条小道将他们连接起来,每条道路都以“尺”为单位去计量,武林盟主发现任何两个门派都能够直接或者间接通过小道连接。虽…

什么是Java Marker Interface(标记接口)

2019独角兽企业重金招聘Python工程师标准>>> 先看看什么是标记接口?标记接口有时也叫标签接口(Tag interface),即接口不包含任何方法。在Java里很容易找到标记接口的例子,比如JDK里的Serializable接口就是一…

JavaWeb项目架构之Kafka分布式日志队列

架构、分布式、日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Kafka做消息队列罢了。 kafka介绍 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布…

ionic 签名、打包

ionic cordova platform add androidionic cordova build android 【debug版本,无需签名】 ionic cordova build android --release 【发布版,需要签名(要使用jarsigner签名必须用release版本)】 ionic cordova build android --r…

Spring框架内容整理(三):AOP

2019独角兽企业重金招聘Python工程师标准>>> AOP面向切面 切面支持类 切面就是通知和切入点的组合,而切面是通过配置方式定义的,因此这定义切面前,我们需要定义切面支持类,切面支持类提供了通知实现 package cn.javass…

python并发编程之多进程理论

一、什么是进程 进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。 举例:单核多道,实现多个进程的并发执行你在一个时间段内有很多任务要做:写python程序,打游戏,逛淘宝  但你同一时刻只能…

python堆排序

堆排序介绍 堆排序,顾名思义,就是基于堆。因此先来介绍一下堆的概念。 堆分为最大堆和最小堆,其实就是完全二叉树。最大堆要求节点的元素都要大于其孩子,最小堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系…

005-统一沟通-部署-基础-环境

准备Active Directory 和域(031-Mail01)安装完成(031-Mail01)为邮箱服务器创建DNS记录(011-DC01)验证DNS邮箱服务器安装证书(031-Mail01)前端服务器验证林准备和域(011-DC01)前端服务器DNS验证(…