---
title: Bitovi Academy - Comparison Operators
description: This week we covered comparisons in JavaScript! The showdown between == and === is on!
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting?hsLang=en-us)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting?hsLang=en-us)
- ![Project management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project management](https://www.bitovi.com/services/agile-project-management-consulting?hsLang=en-us)
- ![Product design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product design](https://www.bitovi.com/services/product-design-consulting?hsLang=en-us)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services?hsLang=en-us)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting?hsLang=en-us)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers?hsLang=en-us)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting?hsLang=en-us)
- [Design Systems](https://www.bitovi.com/services/axure-figma-migration?hsLang=en-us)
- [React](https://www.bitovi.com/services/frontend/react-consulting?hsLang=en-us)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting?hsLang=en-us)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native?hsLang=en-us)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting-1?hsLang=en-us)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study?hsLang=en-us)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign?hsLang=en-us)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work?hsLang=en-us)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source?hsLang=en-us)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about perfecting software delivery
  
  ](https://bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships?hsLang=en-us)
- [![Academy](https://www.bitovi.com/hubfs/limbo/icons/icon-academy.svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy/?hsLang=en-us)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse our tools or contribute to our open source mission.
  
  ](https://www.bitovi.com/open-source?hsLang=en-us)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

- [ Advanced JavaScript ](https://www.bitovi.com/academy/learn-advanced-javascript.html?hsLang=en-us) 
    - [ JavaScript and the DOM ](https://www.bitovi.com/academy/learn-advanced-javascript/js-vs-dom.html?hsLang=en-us)
    - [ Types, Operators and Primitives ](https://www.bitovi.com/academy/learn-advanced-javascript/js-types.html?hsLang=en-us)
    - [ Comparison Operators ](https://www.bitovi.com/academy/learn-advanced-javascript/js-comparison.html?hsLang=en-us)
    - [ Closures ](https://www.bitovi.com/academy/learn-advanced-javascript/closures.html?hsLang=en-us)
    - [ Context ](https://www.bitovi.com/academy/learn-advanced-javascript/context.html?hsLang=en-us)
    - [ Prototypes ](https://www.bitovi.com/academy/learn-advanced-javascript/prototypes.html?hsLang=en-us)
    - [ Classes ](https://www.bitovi.com/academy/learn-advanced-javascript/classes.html?hsLang=en-us)
    - [ Promises ](https://www.bitovi.com/academy/learn-advanced-javascript/promises.html?hsLang=en-us)
- [ DOM and jQuery ](https://www.bitovi.com/academy/learn-dom-jquery.html?hsLang=en-us)
- [ Debug JavaScript ](https://www.bitovi.com/academy/learn-to-debug-javascript.html?hsLang=en-us)
- [ Learn TypeScript ](https://www.bitovi.com/academy/learn-typescript.html?hsLang=en-us)
- [ Learn React Native ](https://www.bitovi.com/academy/learn-react-native.html?hsLang=en-us)
- [ Learn Web Components ](https://www.bitovi.com/academy/learn-web-components.html?hsLang=en-us)
- [ Agile Program Management With Jira ](https://www.bitovi.com/academy/learn-agile-program-management-with-jira.html?hsLang=en-us)
- [ Learn RxJS ](https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us)
- [ Giving a Training ](https://www.bitovi.com/academy/training.html?hsLang=en-us)
- [ Learn Technology Consulting ](https://www.bitovi.com/academy/learn-technology-consulting.html?hsLang=en-us)
- [ Learn React ](https://www.bitovi.com/academy/learn-react.html?hsLang=en-us)
- [ Learn NgRx ](https://www.bitovi.com/academy/learn-ngrx.html?hsLang=en-us)
- [ Learn Graphql ](https://www.bitovi.com/academy/learn-graphql.html?hsLang=en-us)
- [ Learn Docker ](https://www.bitovi.com/academy/learn-docker.html?hsLang=en-us)
- [ Learn CanJS ](https://www.bitovi.com/academy/learn-canjs.html?hsLang=en-us)
- [ Learn Angular ](https://www.bitovi.com/academy/learn-angular.html?hsLang=en-us)
- [ Advanced TypeScript ](https://www.bitovi.com/academy/advanced-typescript.html?hsLang=en-us)

[View More Courses](https://www.bitovi.com/academy/#courses) [ ]

# Comparison Operators `page`

This week we covered comparisons in JavaScript! The showdown between == and === is on!

## Overview

- Byte comparisons
- Memory address comparisons
- `==` state machine
- `===` state machine
- Live examples!

## Video

## Slides

## Exercise

Implement the `eqeq` function. Click `Run in your browser` after the following example:

```
<p>Welcome to the <code>==</code> exercise! Open the JavaScript panel
    to implement the <code>eqeq()</code> function. </p>

<div id="qunit"></div>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.12.0.css">
<script src="//code.jquery.com/qunit/qunit-1.12.0.js"></script>

<script type="module">
// Start by filling this function out!
// eqeq(null, undefined) //-> true
var eqeq = function(value1, value2){

};

// The following functions might be useful to
// eqeq().  You’ll have to implement them yourself.

// Returns true if the value is `null` or `undefined`
var isNullOrUndefined = function(value) {

};

// Given a value, returns the primitive version of it,
// either a number or string.
var toPrimitive = function(value) {

};

// Given an object and a property on the object, this
// will return the property value as long as the property
// is not on `Object.prototype`. If you don’t know what
// this means, copy it from the answer key :-).
var getDefinedPropertyNotOnObjectPrototype = function(obj, prop) {

}

// Test code.  There’s no need to edit the following:
QUnit.module("Double Equal", {});

QUnit.test("Types the same", function(){
  QUnit.equal( eqeq(1,1), 1 == 1 , "1==1");
  QUnit.equal( eqeq('1','1'), '1' == '1' , "'1'=='1'")
  QUnit.equal( eqeq({},{}), {} == {} , "{}=={}")
  QUnit.equal( eqeq(NaN,NaN), NaN == NaN , "NaN==NaN")
});

QUnit.test("Both null or undefined", function(){
  QUnit.equal( eqeq(null,undefined), null == undefined , "null==undefined");
  QUnit.equal( eqeq(undefined,null), undefined ==  null, "undefined==null");
});

QUnit.test("String == Number", function(){
  QUnit.equal( eqeq(1,'1'), 1=='1' , "1=='1'");
  QUnit.equal( eqeq(1,'2'), 1=='2', "1=='2'");
  QUnit.equal( eqeq(1,'a'), 1=='a', "1=='a'");

  QUnit.equal( eqeq('1',1), '1'==1 , "'1'==1");
  QUnit.equal( eqeq('a',1), 'a'==1, "'a'==1");
});

QUnit.test("Boolean == Anything", function(){
  QUnit.equal( eqeq(true,1), true==1 , "true==1");
  QUnit.equal( eqeq(true,2), true==2 , "true==2");
  QUnit.equal( eqeq(true,'true'), true=='true' , "true=='true'");
  QUnit.equal( eqeq(true,'1'), true=='1' , "true=='1'");

  QUnit.equal( eqeq(false,0), false==0 , "false==0");
  QUnit.equal( eqeq(false,'false'), false=='false' , "false=='false'");
  QUnit.equal( eqeq(false,'0'), false=='0' , "false=='0'");

  QUnit.equal( eqeq(1,true), 1==true , "1==true");
  QUnit.equal( eqeq(2,true), 2==true , "2==true");
  QUnit.equal( eqeq('true',true), 'true'==true , "'true'==true");
  QUnit.equal( eqeq('1',true), '1'==true , "'1'==true");

});

QUnit.test("Object == (String || Number)", function(){
  QUnit.equal( eqeq(({toString: function(){return 1}}),1),   ({toString: function(){return 1}})==1 , "({toString: function(){return 1}})==1");
  QUnit.equal( eqeq(({toString: function(){return '1'}}),1), ({toString: function(){return '1'}})==1 , "({toString: function(){return '1'}})==1");
  QUnit.equal( eqeq(({toString: function(){return true}}),1), ({toString: function(){return true}})==1 , "({toString: function(){return true}})==1");

  QUnit.equal( eqeq(({valueOf: function(){return 1}}),1), ({valueOf: function(){return 1}})==1 , "({valueOf: function(){return 1}})==1");
  QUnit.equal( eqeq(({valueOf: function(){return '1'}}),1), ({valueOf: function(){return '1'}})==1 , "({valueOf: function(){return '1'}})==1");
  QUnit.equal( eqeq(({valueOf: function(){return true}}),1), ({valueOf: function(){return true}})==1 , "({valueOf: function(){return true}})==1");

  QUnit.equal( eqeq(({toString: function(){return 1}}),true), ({toString: function(){return 1}})==true , "({toString: function(){return 1}})==true");
  QUnit.equal( eqeq(({toString: function(){return '1'}}),true), ({toString: function(){return '1'}})==true , "({toString: function(){return '1'}})==true");
  QUnit.equal( eqeq(({toString: function(){return true}}),true), ({toString: function(){return true}})==true , "({toString: function(){return true}})==true");

  QUnit.equal( eqeq(({valueOf: function(){return 0}}),false), ({valueOf: function(){return 0}})==false , "({valueOf: function(){return 0}})==false");
  QUnit.equal( eqeq(({valueOf: function(){return null}}),false), ({valueOf: function(){return null}})==false , "({valueOf: function(){return null}})==false");
  QUnit.equal( eqeq(({valueOf: function(){return undefined}}),false), ({valueOf: function(){return undefined}})==false , "({valueOf: function(){return undefined}})==false");

  // odd one
  QUnit.equal( eqeq('a', ({valueOf: function(){return true}, toString: function(){ return 'a' }})), 'a' == ({valueOf: function(){return true}, toString: function(){ return 'a' }}) , "'a' == ({valueOf: function(){return true}, toString: function(){ return 'a' }})");
  QUnit.equal( eqeq(1, [1]), 1 == [1] , "1 == [1]");

  // Hard one
  QUnit.equal( eqeq( "abc" , Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}}) ), "abc" == Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}}) , '"abc" == Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}})');
});
</script>
```

## Solution

```
<div id="qunit"></div>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.12.0.css">
<script src="//code.jquery.com/qunit/qunit-1.12.0.js"></script>
<script type="module">
var eqeq = function(value1, value2){
  var type1 = typeof value1,
      type2 = typeof value2;

  if(type1 === type2) {
    return value1 === value2
  }
  if(isNullOrUndefined(value1) && isNullOrUndefined(value2)) {
    return true;
  }

  if(type1 === "string" && type2 === "number") {
    return eqeq( toPrimitive(value1), value2 );
  }
  if(type2 === "string" && type1 === "number") {
    return eqeq( value1, toPrimitive(value2) );
  }
  if(type1 === "boolean") {
    return eqeq(toPrimitive(value1), value2);
  }
  if(type2 === "boolean") {
    return eqeq(value1, toPrimitive(value2));
  }
  if(value1 && type1 === "object") {
    return eqeq(toPrimitive(value1), value2);
  }
  if(value2 && type2 === "object") {
    return eqeq(value1, toPrimitive(value2));
  }
  return false;
};

var isNullOrUndefined = function(value) {
  return value === null || value === undefined;
};

var toPrimitive = function(value) {
  if(typeof value === "string") {
    return +value;
  }
  if(typeof value === "boolean") {
    return value ? 1 : 0;
  }
  if(typeof value === "object") {
    if(getDefinedPropertyNotOnObjectPrototype(value, "valueOf")) {
      return value.valueOf();
    }
    if(getDefinedPropertyNotOnObjectPrototype(value, "toString")) {
      return value.toString();
    }
    return value.valueOf();
  }
};

var getDefinedPropertyNotOnObjectPrototype = function(obj, prop) {
  if( obj.hasOwnProperty(prop) ) {
    return obj[prop]
  }
  if(Object.getPrototypeOf(obj) !== Object.prototype) {
    return getDefinedPropertyNotOnObjectPrototype(Object.getPrototypeOf(obj), prop);
  }
}

QUnit.module("Double Equal", {});

QUnit.test("Types the same", function(){
  QUnit.equal( eqeq(1,1), 1 == 1 , "1==1");
  QUnit.equal( eqeq('1','1'), '1' == '1' , "'1'=='1'")
  QUnit.equal( eqeq({},{}), {} == {} , "{}=={}")
  QUnit.equal( eqeq(NaN,NaN), NaN == NaN , "NaN==NaN")
});

QUnit.test("Both null or undefined", function(){
  QUnit.equal( eqeq(null,undefined), null == undefined , "null==undefined");
  QUnit.equal( eqeq(undefined,null), undefined ==  null, "undefined==null");
});

QUnit.test("String == Number", function(){
  QUnit.equal( eqeq(1,'1'), 1=='1' , "1=='1'");
  QUnit.equal( eqeq(1,'2'), 1=='2', "1=='2'");
  QUnit.equal( eqeq(1,'a'), 1=='a', "1=='a'");

  QUnit.equal( eqeq('1',1), '1'==1 , "'1'==1");
  QUnit.equal( eqeq('a',1), 'a'==1, "'a'==1");
});

QUnit.test("Boolean == Anything", function(){
  QUnit.equal( eqeq(true,1), true==1 , "true==1");
  QUnit.equal( eqeq(true,2), true==2 , "true==2");
  QUnit.equal( eqeq(true,'true'), true=='true' , "true=='true'");
  QUnit.equal( eqeq(true,'1'), true=='1' , "true=='1'");

  QUnit.equal( eqeq(false,0), false==0 , "false==0");
  QUnit.equal( eqeq(false,'false'), false=='false' , "false=='false'");
  QUnit.equal( eqeq(false,'0'), false=='0' , "false=='0'");

  QUnit.equal( eqeq(1,true), 1==true , "1==true");
  QUnit.equal( eqeq(2,true), 2==true , "2==true");
  QUnit.equal( eqeq('true',true), 'true'==true , "'true'==true");
  QUnit.equal( eqeq('1',true), '1'==true , "'1'==true");

});

QUnit.test("Object == (String || Number)", function(){
  QUnit.equal( eqeq(({toString: function(){return 1}}),1),   ({toString: function(){return 1}})==1 , "({toString: function(){return 1}})==1");
  QUnit.equal( eqeq(({toString: function(){return '1'}}),1), ({toString: function(){return '1'}})==1 , "({toString: function(){return '1'}})==1");
  QUnit.equal( eqeq(({toString: function(){return true}}),1), ({toString: function(){return true}})==1 , "({toString: function(){return true}})==1");

  QUnit.equal( eqeq(({valueOf: function(){return 1}}),1), ({valueOf: function(){return 1}})==1 , "({valueOf: function(){return 1}})==1");
  QUnit.equal( eqeq(({valueOf: function(){return '1'}}),1), ({valueOf: function(){return '1'}})==1 , "({valueOf: function(){return '1'}})==1");
  QUnit.equal( eqeq(({valueOf: function(){return true}}),1), ({valueOf: function(){return true}})==1 , "({valueOf: function(){return true}})==1");

  QUnit.equal( eqeq(({toString: function(){return 1}}),true), ({toString: function(){return 1}})==true , "({toString: function(){return 1}})==true");
  QUnit.equal( eqeq(({toString: function(){return '1'}}),true), ({toString: function(){return '1'}})==true , "({toString: function(){return '1'}})==true");
  QUnit.equal( eqeq(({toString: function(){return true}}),true), ({toString: function(){return true}})==true , "({toString: function(){return true}})==true");

  QUnit.equal( eqeq(({valueOf: function(){return 0}}),false), ({valueOf: function(){return 0}})==false , "({valueOf: function(){return 0}})==false");
  QUnit.equal( eqeq(({valueOf: function(){return null}}),false), ({valueOf: function(){return null}})==false , "({valueOf: function(){return null}})==false");
  QUnit.equal( eqeq(({valueOf: function(){return undefined}}),false), ({valueOf: function(){return undefined}})==false , "({valueOf: function(){return undefined}})==false");

  // odd one
  QUnit.equal( eqeq('a', ({valueOf: function(){return true}, toString: function(){ return 'a' }})), 'a' == ({valueOf: function(){return true}, toString: function(){ return 'a' }}) , "'a' == ({valueOf: function(){return true}, toString: function(){ return 'a' }})");
  QUnit.equal( eqeq(1, [1]), 1 == [1] , "1 == [1]");

  // Hard one
  QUnit.equal( eqeq( "abc" , Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}}) ), "abc" == Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}}) , '"abc" == Object.create({valueOf: function(){return "abc"}}, {toString: {value: function(){ return "ABC" }}})');
});
</script>
```

###### On this page...

###### Get help

If you need [help](https://discord.gg/J7ejFsZnJ4) with an exercise, please reach out to us on [Discord](https://discord.gg/J7ejFsZnJ4)

If you find a bug, please [create an issue](https://github.com/bitovi/academy/issues/new) or email [contact@bitovi.com](mailto:contact@bitovi.com?Subject=Training%20Suggestion)

## Join the Bitovi Newsletter

 Do you want to receive updates about new Bitovi Academy courses, Bitovi open source projects, and dev community news? If so, please provide your email. We won’t spam you or give it away for any reason!  
*By providing your email you agree to receive communications from Bitovi*

![](https://bitovi.github.io/academy/static/img/close.svg)

```json
{
     "@context": "http://schema.org",
     "@type": "Organization",
     "mainEntityOfPage":{
          "@type":"WebPage",
          "@id":"https://www.bitovi.com/academy/learn-advanced-javascript/js-comparison.html",
          "description": "This week we covered comparisons in JavaScript! The showdown between == and === is on! 
"
     },
     "url": "http://bitovi.com",
     "logo": "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
     "image": "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
     "name": "Bitovi Web App Consulting",
     "alternateName": "Bitovi",
      "naics": "541511",
      "description": "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
     "address": {
          "@type": "PostalAddress",
          "streetAddress": "1134 Pine Tree Lane ",
          "addressLocality": "Libertyville",
          "addressRegion": "IL",
          "addressCountry": "United States",
          "postalCode": "60048"
     },
     "areaServed": {
          "@type": "GeoCircle",
          "geoMidpoint": {
               "@type": "GeoCoordinates",
               "latitude": "41.8781",
               "longitude": "87.6298"
          },
          "geoRadius": "5000 km"
     },
     "telephone": "312-620-0386",
     "email": "contact@bitovi.com",
     "sameAs": [
          "https://www.facebook.com/BitoviLLC/",
          "https://twitter.com/bitovi",
          "https://www.linkedin.com/company/bitovi"
     ]
}
```