JavaScript Prototypical Inheritance and this​

by Jedediah Smith

Who I Am

  • Jedediah Smith
  • Work for CurbNTurf
  • A book I work on off and on: JedJS.com
  • Twitter: @jedsmith13
  • LinkedIn: https://www.linkedin.com/in/jedediahsmith

What Is CurbNTurf

  • A multi-sided platform for connecting the RVer with Land Owners.
  • A young startup.
  • Written in JavaScript on the front-end and the back-end.
  • Just opened a beta and are allowing Land Owners to sign up.
  • Hiring a front-end developer.
  • Contact me if you are interested in when we open it up to guests, signing up as a host, or a job.

SR-71

SR-71

  • Top speed: 2200mph
  • 2x Pratt & Whitney J58-1 (34,000lbf Each)
  • Wingspan: 55' 7"
  • Length 107' 5"
  • Empty weight: 67,500lb
  • Loaded weight: 152,000lb
  • Introduced: 1966
  • Retired: 1999

SR-71

  • When building an aircraft as advanced as the SR-71 you start by building a prototype that you can modify and change to workout the bugs.
  • Prototypes are often built based off other similar designs.
  • Prototypes can also be used to make minor model changes.
  • Not all prototypes work out.

Arduino

Arduino

  • Has a microcontroller allowing it to be programmed
  • Inexpensive to buy
  • Numerous shields, modules, and components which can work with it.
  • Allows a huge number of possibilities
  • Used for prototyping concepts

Arduino

  • Take a base controller and add functionality
  • Easily add new functionality as desired
  • Can replace functionality if something better is needed

JavaScript's Prototypical Inheritance

  • How does it work
  • How do I use it

How Does JavaScript's Prototypical Inheritance Work

  • Chaining
  • this

Chaining

obj

{}

obj.toString()

obj.getSomething

obj.doThis()

obj.doThat()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

obj

{}

obj.toString()

obj.getSomething

obj.doThis()

obj.doThat()

Object

null

Parent 1

{

doThat: function

}

 

Parent 2

Parent 3

Parent 4

Parent 5

obj

{}

obj.toString()

obj.getSomething

obj.doThis()

obj.doThat()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Parent 2

{

doThis: function

}

 

obj

{}

obj.toString()

obj.getSomething

obj.doThis()

obj.doThat()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Parent 4

{

getSomething: 1

}

 

obj

{}

obj.toString()

obj.getSomething

obj.doThis()

obj.doThat()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Object

{

toString: function

}

 

obj

{}

obj.nothing()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

obj

{

local: function

}

obj.local()

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Arduino

=

Humidity and Temperature Sensor (DHT11)

  • 1Hz Sample rate
  • 20-80% humidity range
  • 5% humidity accuracy
  • 0-50°C temperature range
  • ±2°C temperature accuracy

 

Need to measure winter temperatures in Idaho record low in Boise is  -33.33°C

Arduino

Voltage Output Temperature Sensor (TMP36)

  • -40-125°C temperature range
  • ±2°C temperature accuracy

 

Arduino

=

Humidity and Temperature sensor(s)

  • 1Hz Sample rate
  • 20-80% humidity range
  • 5% humidity accuracy
  • -40-125°C temperature range
  • ±2°C temperature accuracy

 

Need to measure winter temperatures in Idaho record low in Boise is  -33.33°C

+

What about "this"

obj

{}

obj.setName()

obj.getName()

 

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Parent 4

{
  setName: function (name) {
    this.name = name;
  },
  getName: function () {
    return this.name;
  }
}

With "this"

obj

{

  name: 'Me'

}

obj.setName('Me')

obj.getName()

 

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Parent 4

{
  setName: function (name) {
    this.name = name;
  },
  getName: function () {
    return this.name;
  }
}

With "this"

returns 'Me'

obj

{

  name: 'Me'

}

obj.setName('You')

obj.getName()

 

Object

null

Parent 1

Parent 2

Parent 3

Parent 4

Parent 5

Parent 4

var name;
{
  setName: function (newName) {
    name = newName;
  },
  getName: function () {
    return name;
  }
}

Without "this"

returns 'You'

How Do I Use JavaScript's Prototypical Inheritance

  • new
  • Object.create()
  • class

new

function Foo(a) {
    this.a = a;
    var b; //Careful with this
}

Foo.prototype.createBar = function (bar) {
    this.bar = bar;
}

Foo.prototype.setB = function (newB) {
    b = newB;
}

Foo.prototype.getB = function () {
    return b;
}

var foo = new Foo('JavaScript Prototypes');

foo.createBar('Boise Code Camp');

foo.setB('Store hidden');

foo.a; //JavaScript Prototypes
foo.bar; //Boise Code Camp

foo.b; //undefined
foo.getB(); //Store hidden

Hidden variables with new??

function Foo(a) {
    this.a = a;
    var b;
}

Foo.prototype.setB = function (newB) {
    b = newB;
}

Foo.prototype.getB = function () {
    return b;
}

var foo = new Foo('JavaScript Prototypes');

foo.setB('Store hidden');

foo.getB(); //Store hidden

var foo2 = new Foo('JavaScript Prototypes 2');

foo2.getB(); //Store hidden

foo2.setB('Store shared');

foo2.getB(); //Store shared
foo.getB(); //Store shared

Object.create()

var someObj = {
    createBar: function (bar) {
        this.bar = bar;
    }
}

var foo3 = Object.create(someObj);
foo3.a = 'JavaScript Prototypes';
foo3.createBar('Boise Code Camp');

foo3.a; //JavaScript Prototypes
foo3.bar; //Boise Code Camp

//Doesn't do what you want
var foo4 = Object.create(Foo); // Foo is really just a function

//Instead you would do
var foo5 = Object.create(foo); // foo is already an instance of Foo
//or
var foo6 = Object.create(Foo.prototype); // Foo's prototype can be used to create a function

class

class Foo {
    constructor(a) {
        this.a = a;
    }

    createBar(bar) {
        this.bar = bar;
    }

}

var foo = new Foo('JavaScript Prototypes');
foo.createBar('Boise Code Camp');

console.log(foo.a);
console.log(foo.bar);

More about 'this'

What 'this' is 'this'?

const foo = {
    a: true,
    get: function() {
        fetch('https://xkcd.com/562/info.0.json', {mode: 'no-cors'})
            .then(function(result) { 
                if (this.a) {
                    return console.log(result);
                } 
                return console.log('No this.a');
            }
        );
    }
};

const foo2 = Object.create(foo);
window.a = true;

foo2.get(); //Response
foo2.get(); // this.a doesn't exist

Object.bind()

const foo = {
    a: true,
    get: function() {
        fetch('https://xkcd.com/562/info.0.json', {mode: 'no-cors'})
            .then(function(result) { 
                if (this.a) {
                    return console.log(result);
                } 
                return console.log('No this.a');
            }.bind(this)
        );
    }
};

const foo2 = Object.create(foo);

foo2.get(); //Response

Arrow function

() => {} // ECMAScript 2015

const foo = {
    a: true,
    get: function() {
        fetch('https://xkcd.com/562/info.0.json', {mode: 'no-cors'})
            .then((result) => { 
                if (this.a) {
                    return console.log(result);
                } 
                return console.log('No this.a');
            }
        );
    }
};

const foo2 = Object.create(foo);

foo2.get(); //Response

Mixins

const fooA = {
    doA: function() {
        console.log('Consider A done');
    }
};
const fooB = {
    doB: function() {
        console.log('Consider B done');
    }
};
const fooC = {
    doC: function() {
        console.log('Consider C done');
    }
};

const foo = Object.create(fooA);

Object.assign(foo, fooB, fooC);

foo.doA(); // Consider A done
foo.doB(); // Consider B done
foo.doC(); // Consider C done

Mixins

const fooA = {
    doA: function() {
        console.log('Consider A done');
    },
    doB: function() {
        console.log('Consider A\'s version of doB done');
    }
};
const fooB = {
    doB: function() {
        console.log('Consider B done');
    }
};

const foo = Object.create(fooA);

Object.assign(foo, fooB);

foo.doA(); // Consider A done
foo.doB(); // Consider B done

Not: Consider A's version of doB done

Mixins with class

const FooA = (existingClass) => class extends existingClass {
    doA() { console.log('Consider A done'); }
};
const FooB = (existingClass) => class extends existingClass {
    doB() { console.log('Consider B done'); }
};

class Foo {
    isFoo() { return true; }
}

class FooAB extends FooA(FooB(Foo)) {
    doAB() { console.log('Sorry I am lost'); }
}

const foo = new FooAB();

foo.doA(); //Consider A done
foo.doB(); //Consider B done
foo.doAB(); //Sorry I am lost
foo.isFoo(); //true

Advantages of Using JavaScript's Prototypical Inheritance

  • Encapsulation
  • Reusable functions
  • Reduce code
  • Dynamic inheritance
Made with Slides.com