prototypal inheritance in javascript

119
Prototypal inheritance in JavaScript #JavaScript #Prototype #Inheritance Miroslav Obradović [email protected] http://www.youngculture.com

Upload: miroslav-obradovic

Post on 11-Aug-2015

199 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Prototypal inheritance in JavaScript

Prototypal inheritancein JavaScript

#JavaScript #Prototype #Inheritance

Miroslav Obradović[email protected]

http://www.youngculture.com

Page 2: Prototypal inheritance in JavaScript

Object is not a primitive

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

Page 3: Prototypal inheritance in JavaScript

Object is not a primitive

[ 1, 3, 5, 7, 9 ]; var odd = console.log(odd.length); // 5

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

Page 4: Prototypal inheritance in JavaScript

Object is not a primitive

[ 1, 3, 5, 7, 9 ]; var odd = console.log(odd.length); // 5

/match-me/i; var regex = console.log(regex.ignoreCase); // true

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

Page 5: Prototypal inheritance in JavaScript

Object is not a primitive

[ 1, 3, 5, 7, 9 ]; var odd = console.log(odd.length); // 5

/match-me/i; var regex = console.log(regex.ignoreCase); // true

function (name) {

alert('Hello,' + name);

};

var greet = console.log(greet.length); // 1

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

Page 6: Prototypal inheritance in JavaScript

Object is not a primitive

[ 1, 3, 5, 7, 9 ]; var odd = console.log(odd.length); // 5

/match-me/i; var regex = console.log(regex.ignoreCase); // true

function (name) {

alert('Hello,' + name);

};

var greet = console.log(greet.length); // 1

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

var message = 'Welcome!';

var count = 0;

var flag = false;

Page 7: Prototypal inheritance in JavaScript

Object is not a primitive

var blank = null;

var nothing = undefined;

[ 1, 3, 5, 7, 9 ]; var odd = console.log(odd.length); // 5

/match-me/i; var regex = console.log(regex.ignoreCase); // true

function (name) {

alert('Hello,' + name);

};

var greet = console.log(greet.length); // 1

{

name: 'John Doe',

married: false,

age: 25,

};

var person = console.log(person.name); // John Doe

var message = 'Welcome!';

var count = 0;

var flag = false;

Page 8: Prototypal inheritance in JavaScript

Theory of strings?!

Page 9: Prototypal inheritance in JavaScript

Theory of strings?!

var obj = {};

obj[null] = 42;

console.log(obj.hasOwnProperty('null'));

// true

console.log(obj['null']);

// 42

Page 10: Prototypal inheritance in JavaScript

Theory of strings?!

var obj = {};

obj[null] = 42;

console.log(obj.hasOwnProperty('null'));

// true

console.log(obj['null']);

// 42

var a = ['zero','one','two'];

a['3'] = 'three';

console.log(a[1]);

// one

console.log(a['1']);

// one

console.log(a[3]);

// three

console.log(a['3']);

// three

console.log(a.length);

// 4

Page 11: Prototypal inheritance in JavaScript

Theory of strings?!

var obj = {};

obj[null] = 42;

console.log(obj.hasOwnProperty('null'));

// true

console.log(obj['null']);

// 42

var a = ['zero','one','two'];

a['3'] = 'three';

console.log(a[1]);

// one

console.log(a['1']);

// one

console.log(a[3]);

// three

console.log(a['3']);

// three

console.log(a.length);

// 4

var a = ['x','y','z'];

a['test'] = 'array is object';

console.log(a['test']);

// array is object

console.log(a.length);

// 3

Page 12: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

Page 13: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

var n;

console.log(n);

// undefined

Page 14: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

var n;

console.log(n);

// undefined

var obj = {

abc: 55

};

console.log(obj.xyz);

// undefined

Page 15: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

var n;

console.log(n);

// undefined

function f (arg) {

console.log(arg);

}

f();

// undefined

var obj = {

abc: 55

};

console.log(obj.xyz);

// undefined

Page 16: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

var n;

console.log(n);

// undefined

function f (arg) {

console.log(arg);

}

f();

// undefined

function nop () {

// return omitted

}

console.log(nop());

// undefined

var obj = {

abc: 55

};

console.log(obj.xyz);

// undefined

Page 17: Prototypal inheritance in JavaScript

null vs. undefined

console.log(typeof null === 'object'); // true

console.log(typeof undefined === 'undefined'); // true

var n;

console.log(n);

// undefined

function f (arg) {

console.log(arg);

}

f();

// undefined

function nop () {

// return omitted

}

console.log(nop());

// undefined

var obj = {

abc: 55

};

console.log(obj.xyz);

// undefined

function ret () {

return;

}

console.log(ret());

// undefined

Page 18: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

Page 19: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

Page 20: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

console.log(joe.weight);

// 82

Page 21: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

console.log(joe.weight);

// 82

console.log(joe.height);

// undefined

Page 22: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

{

name: 'Eva',

weight: undefined

};

var eva =

console.log(joe.weight);

// 82

console.log(joe.height);

// undefined

Page 23: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

{

name: 'Eva',

weight: undefined

};

var eva =

console.log(eva.age);

// 21

console.log(joe.weight);

// 82

console.log(joe.height);

// undefined

Page 24: Prototypal inheritance in JavaScript

Inheriting from another object

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

console.log(joe.age);

// 25

{

name: 'Eva',

weight: undefined

};

var eva =

console.log(eva.age);

// 21

console.log(joe.weight);

// 82

console.log(joe.height);

// undefined

console.log(eva.weight);

// undefined

Page 25: Prototypal inheritance in JavaScript

Hide and seek!

{

name: 'Joe'

};

var joe = {

age: 21,

weight: 82,

favorites: {

car: 'yugo'

}

};

null

Page 26: Prototypal inheritance in JavaScript

Hide and seek!

{

name: 'Joe'

};

var joe = {

age: 21,

weight: 82,

favorites: {

car: 'yugo'

}

};

null

console.log(joe.age); // 21

Page 27: Prototypal inheritance in JavaScript

Hide and seek!

{

name: 'Joe'

};

var joe = {

age: 21,

weight: 82,

favorites: {

car: 'yugo'

}

};

null

,

age: 25

joe.age = 25;

console.log(joe.age); // 25

console.log(joe.age); // 21

Page 28: Prototypal inheritance in JavaScript

Hide and seek!

{

name: 'Joe'

};

var joe = {

age: 21,

weight: 82,

favorites: {

car: 'yugo'

}

};

null

,

age: 25

joe.age = 25;

console.log(joe.age); // 25

,

food: 'jelly'

joe.favorites.food = 'jelly';console.log(joe.age); // 21

Page 29: Prototypal inheritance in JavaScript

Hide and seek!

{

name: 'Joe'

};

var joe = {

age: 21,

weight: 82,

favorites: {

car: 'yugo'

}

};

null

,

age: 25

joe.age = 25;

console.log(joe.age); // 25

,

food: 'jelly'

joe.favorites.food = 'jelly';

,

favorites: {

food: 'plums'

}

joe.favorites = {

food: 'plums'

};

console.log(joe.age); // 21

Page 30: Prototypal inheritance in JavaScript

Bound in prototype chains?

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

null

Page 31: Prototypal inheritance in JavaScript

Bound in prototype chains?

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

{

height: 185

};

null

Page 32: Prototypal inheritance in JavaScript

Bound in prototype chains?

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

{

height: 185

};

Page 33: Prototypal inheritance in JavaScript

[[Prototype]] & _ _proto_ _

Page 34: Prototypal inheritance in JavaScript

[[Prototype]] & _ _proto_ _

null

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

[[Prototype]]

_ _proto_ _

Page 35: Prototypal inheritance in JavaScript

[[Prototype]] & _ _proto_ _

null

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

[[Prototype]]

_ _proto_ _

console.log(joe.age);

// 25

Page 36: Prototypal inheritance in JavaScript

[[Prototype]] & _ _proto_ _

null

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

[[Prototype]]

_ _proto_ _

console.log(joe.age);

// 25

console.log(joe._ _proto_ _.age);

// 21

Page 37: Prototypal inheritance in JavaScript

[[Prototype]] & _ _proto_ _

null

{

name: 'Joe',

age: 25

};

var joe = {

age: 21,

weight: 82

};

[[Prototype]]

_ _proto_ _

console.log(joe.age);

// 25

console.log(joe._ _proto_ _.age);

// 21

console.log(joe._ _proto_ _._ _proto_ _);

// null

Page 38: Prototypal inheritance in JavaScript

prototype property

var F = function () {};

Page 39: Prototypal inheritance in JavaScript

prototype property

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

Page 40: Prototypal inheritance in JavaScript

prototype property

console.log(typeof F);

// function

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

Page 41: Prototypal inheritance in JavaScript

prototype property

console.log(typeof F);

// function

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

console.log(typeof F.prototype);

// object

Page 42: Prototypal inheritance in JavaScript

prototype property

console.log(typeof F);

// function

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

console.log(typeof F.prototype);

// object

console.log(F.prototype.constructor === F);

// true

Page 43: Prototypal inheritance in JavaScript

prototype property

console.log(typeof F);

// function

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

console.log(typeof F.prototype);

// object

console.log(F.prototype.constructor === F);

// true

console.log(F.prototype.prototype);

// undefined

Page 44: Prototypal inheritance in JavaScript

prototype property

console.log(typeof F);

// function

var F = function () {};

__proto__function () {};

{

length: 0,

prototype

}

var F =

_ _proto_ _

{

constructor: F

}

console.log(F.prototype !== F._ _proto_ _);

// true

console.log(typeof F.prototype);

// object

console.log(F.prototype.constructor === F);

// true

console.log(F.prototype.prototype);

// undefined

Page 45: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function () {};

Page 46: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

Page 47: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

var o = new F();

Page 48: Prototypal inheritance in JavaScript

prototype property & operator new

new F();var o =

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

var o = new F();

Page 49: Prototypal inheritance in JavaScript

prototype property & operator new

new F();var o =

console.log(o._ _proto_ _ === F.prototype);

// true

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

var o = new F();

Page 50: Prototypal inheritance in JavaScript

prototype property & operator new

new F();var o =

console.log(o._ _proto_ _ === F.prototype);

// true

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

new F();var p =

var o = new F();

Page 51: Prototypal inheritance in JavaScript

prototype property & operator new

new F();var o =

console.log(o._ _proto_ _ === F.prototype);

// true

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

new F();var p =

new F();var q =

var o = new F();

Page 52: Prototypal inheritance in JavaScript

prototype property & operator new

new F();var o =

console.log(o._ _proto_ _ === F.prototype);

// true

var F = function () {};

_ _proto_ _

{

constructor: F

}

__proto__function () {};

{

length: 0,

prototype

}

var F =

……

new F();var p =

new F();var q =

var o = new F();

Page 53: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

Page 54: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

Page 55: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

Page 56: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

Page 57: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

{ val: 11 };var objX =

Page 58: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

{ val: 11 };var objX =

objX.print(); // 11

Page 59: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

{ val: 11 };var objX =

objX.print(); // 11

var objY = new F(45);

Page 60: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

{ val: 11 };var objX =

objX.print(); // 11

var objY = new F(45);

{ val: 45 };var objY =

Page 61: Prototypal inheritance in JavaScript

prototype property & operator new

var F = function (val) {

this.val = val;

};

{

constructor: F

}

function (val) {

this.val = val;

};

{

prototype

}

var F =

,

print: function () {

console.log(this.val);

}

F.prototype.print = function () {

console.log(this.val);

};

var objX = new F(11);

{ val: 11 };var objX =

objX.print(); // 11

var objY = new F(45);

{ val: 45 };var objY =

objY.print(); // 45

Page 62: Prototypal inheritance in JavaScript

WTF is this?

Page 63: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

Page 64: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

Page 65: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

Page 66: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

Page 67: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

Page 68: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

f.call(42, args); // new Number(42)

Page 69: Prototypal inheritance in JavaScript

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

obj.m(args); // obj

array[0](args); // array

f.call(42, args); // new Number(42)

Page 70: Prototypal inheritance in JavaScript

var g = obj.m;

g(args);

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

obj.m(args); // obj

array[0](args); // array

f.call(42, args); // new Number(42)

Page 71: Prototypal inheritance in JavaScript

var g = obj.m;

g(args);

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

obj.m(args); // obj

array[0](args); // array

// window

f.call(42, args); // new Number(42)

Page 72: Prototypal inheritance in JavaScript

var g = obj.m;

g(args);

WTF is this?

var f = function (args) {

console.log(this);

};

var obj = { m: f };

var array = [ f ];

new f(args); // new object

f(args); // window

f.call(context, args); // context object

f.apply(context, [args]); // context object

f.call(null, args); // window

f.call(undefined, args); // window

obj.m(args); // obj

array[0](args); // array

What is this inside a function is determined when the function is invoked, not when it is defined!

// window

f.call(42, args); // new Number(42)

Page 73: Prototypal inheritance in JavaScript

Something in return?

Page 74: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

Page 75: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

Page 76: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 77: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

new g(); // new object

g(); // -1 (null, undefined or primitive)

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 78: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

new g(); // new object

g(); // -1 (null, undefined or primitive)

var h = function () {

return { val: 42 };

};

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 79: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

new g(); // new object

g(); // -1 (null, undefined or primitive)

new h(); // { val: 42 }

h(); // { val: 42 }

var h = function () {

return { val: 42 };

};

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 80: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

var wtf = function () {

return

{ val: 42 };

};

new g(); // new object

g(); // -1 (null, undefined or primitive)

new h(); // { val: 42 }

h(); // { val: 42 }

var h = function () {

return { val: 42 };

};

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 81: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

var wtf = function () {

return

{ val: 42 };

};

new wtf(); // new object

wtf(); // undefined

new g(); // new object

g(); // -1 (null, undefined or primitive)

new h(); // { val: 42 }

h(); // { val: 42 }

var h = function () {

return { val: 42 };

};

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 82: Prototypal inheritance in JavaScript

Something in return?

var f = function () {

return; // or w/o return

};

new f(); // new object

f(); // undefined

var wtf = function () {

return

{ val: 42 };

};

new wtf(); // new object

wtf(); // undefined ;

new g(); // new object

g(); // -1 (null, undefined or primitive)

new h(); // { val: 42 }

h(); // { val: 42 }

var h = function () {

return { val: 42 };

};

var g = function () {

// return null, undefined,

// or a primitive value

return -1;

};

Page 83: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

Page 84: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

Page 85: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

{

constructor: F

}

function () {};

{

prototype

}

var F =

Page 86: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

{

constructor: F

}

function () {};

{

prototype

}

var F =

var that = {

}

Page 87: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

{

constructor: F

}

function () {};

{

prototype

}

var F =

var that = {

}

F.prototype = that;

Page 88: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

{

constructor: F

}

function () {};

{

prototype

}

var F =

var that = {

}{}var newObj =

F.prototype = that;

Page 89: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

var newObj = Object.create(that);

{

constructor: F

}

function () {};

{

prototype

}

var F =

var that = {

}{}var newObj =

F.prototype = that;

Page 90: Prototypal inheritance in JavaScript

Inherit from that

function create (that) {

}

var newObj = create(that);

var F = function () {};

return new F();

var newObj = Object.create(that);

var newObj = Object.create(null);

{

constructor: F

}

function () {};

{

prototype

}

var F =

var that = {

}{}var newObj =

F.prototype = that;

Page 91: Prototypal inheritance in JavaScript

instanceof

console.log(objX instanceof F);

Page 92: Prototypal inheritance in JavaScript

instanceof

{

}

var objX =

console.log(objX instanceof F);

Page 93: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

Page 94: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F); // true

Page 95: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

{

}

var objY =

console.log(objY instanceof F);

// true

Page 96: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

{

}

var objY =

console.log(objY instanceof F);

// true

// true

Page 97: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

{

}

var objY =

console.log(objY instanceof F);

console.log(objX.isPrototypeOf(objY)); // true

// true

// true

Page 98: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

{

}

var objY =

console.log(objY instanceof F);

console.log(objX.isPrototypeOf(objY)); // true

console.log(F.prototype.isPrototypeOf(objY)); // true

// true

// true

Page 99: Prototypal inheritance in JavaScript

instanceof

{

constructor: F

}

function () {};

{

prototype

}

var F =

{

}

var objX =

console.log(objX instanceof F);

{

}

var objY =

console.log(objY instanceof F);

console.log(objX.isPrototypeOf(objY)); // true

objX instanceof F <=> F.prototype.isPrototypeOf(objX)

console.log(F.prototype.isPrototypeOf(objY)); // true

// true

// true

Page 100: Prototypal inheritance in JavaScript

Chicken or the egg?

Page 101: Prototypal inheritance in JavaScript

Chicken or the egg?

console.log(Function instanceof Object); // true

Page 102: Prototypal inheritance in JavaScript

Chicken or the egg?

console.log(Object instanceof Function); // true

console.log(Function instanceof Object); // true

Page 103: Prototypal inheritance in JavaScript

Chicken or the egg?

function Function () {

[native code]

}

prototype

_ _proto_ _

function () {}

constructor

_ _proto_ _ …

Page 104: Prototypal inheritance in JavaScript

Chicken or the egg?

function Object () {

[native code]

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _ = null…

Page 105: Prototypal inheritance in JavaScript

Chicken or the egg?

function Object () {

[native code]

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _ = null

function Function () {

[native code]

}

prototype

_ _proto_ _

function () {}

constructor

_ _proto_ _

Page 106: Prototypal inheritance in JavaScript

function Object () {

[native code]

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _ = null

function Function () {

[native code]

}

prototype

_ _proto_ _

function () {}

constructor

_ _proto_ _

new Object()

_ _proto_ _

Page 107: Prototypal inheritance in JavaScript

function Object () {

[native code]

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _ = null

function Function () {

[native code]

}

prototype

_ _proto_ _

function () {}

constructor

_ _proto_ _

function MyFunction () {

// JavaScript code

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _

Page 108: Prototypal inheritance in JavaScript

function Object () {

[native code]

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _ = null

function Function () {

[native code]

}

prototype

_ _proto_ _

function () {}

constructor

_ _proto_ _

function MyFunction () {

// JavaScript code

}

prototype

_ _proto_ _

{}

constructor

_ _proto_ _

new MyFunction()

_ _proto_ _

new Object()

_ _proto_ _

Page 109: Prototypal inheritance in JavaScript

• no classes – only objects and primitive values

• _ _proto_ _ vs. prototype

• one function = two objects

• this & return

• use F.prototype to share properties

• inherit from that

• instanceof vs. Object.isPrototypeOf()

• the map of Function and Object inheritance

• MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript

• Chrome DevTools: http://discover-devtools.codeschool.com

Takeaways

Page 110: Prototypal inheritance in JavaScript

Thank you!

Q & A

Page 111: Prototypal inheritance in JavaScript

BONUSOverview of object oriented

and functional concepts,with examples

Page 112: Prototypal inheritance in JavaScript

Polymorphism – Inheritance

// Base class providing common interface to all subclassesvar Vehicle = function (name, wheels) {this.name = name;this.wheels = wheels;

};Vehicle.prototype.drive = function () {console.log('Driving the ' + this.name + ' on ' + this.wheels + ' wheels');

};

// Subclass with additional methods, sharing the common interfacevar Car = function (doors) {this.superConstructor('car', 4);this.doors = doors;

};// Inherit the base class and keep a reference to the super class constructorCar.prototype = Object.create(Vehicle.prototype); Car.prototype.superConstructor = Vehicle;// Specialized subclass methodsCar.prototype.checkDoors = function () {console.log('This ' + this.name + ' has ' + this.doors + ' doors');

};

// Another subclass sharing the common interfacevar Bicycle = function () {this.superConstructor('bicycle', 2);

};// Inherit the base class and keep a reference to the super class constructorBicycle.prototype = Object.create(Vehicle.prototype); Bicycle.prototype.superConstructor = Vehicle;

// Example

var car = new Car(5);var bicycle = new Bicycle();

car.checkDoors(); // This car has 5 doorscar.drive(); // Driving the car on 4 wheelsbicycle.drive(); // Driving the bicycle on 2 wheels

Page 113: Prototypal inheritance in JavaScript

Polymorphism – Overloading// Behavior depends on the number of supplied argumentsvar argumentCounter = function() {if (arguments.length <= 1) {console.log('Processing at most one argument');

} else {console.log('Processing multiple arguments');

}};

// Behavior depends on the argument typesvar typeChecker = function(arg) {if (typeof arg === 'string') {console.log('Processing a string argument');

} else {console.log('Processing a non-string argument');

}};

// Example

argumentCounter(); // Processing at most one argumentargumentCounter(1, 2, 3); // Processing multiple arguments

typeChecker('test'); // Processing a string argumenttypeChecker(true); // Processing a non-string argument

Page 114: Prototypal inheritance in JavaScript

Encapsulationvar House = function() {var that = {},

privateRoom = function() {console.log('in private');

};

that.publicRoom = function() {console.log('entered public');privateRoom();console.log('exiting public');

};

return that;

};

// Example

var house = new House();house.publicRoom(); // entered public

// in private// exiting public

console.log('privateRoom' in house); // false

Page 115: Prototypal inheritance in JavaScript

Aggregationvar Vehicle = function (name) {return { name: name };

};

var Garage = function() {var that = {}, vehicles = [];

that.add = function(vehicle) {vehicles.push(vehicle);console.log('Added ' + vehicle.name);

};

that.remove = function(vehicle) {var found;vehicles = vehicles.filter(function(v) {found = found || vehicle === v;return vehicle !== v;

});console.log((found ? 'Removed ' : 'Could not remove ') + vehicle.name);

};

that.print = function() {var names = vehicles.map(function(v) {return v.name;

});console.log('Vehicles: ' + names.join(', '));

};

return that;};

// Example

var truck = Vehicle('truck');var car = Vehicle('car');var bicycle = Vehicle('bicycle');

var garage = Garage();

garage.add(car); // Added cargarage.add(bicycle); // Added bicyclegarage.print(); // Vehicles: car, bicycle

garage.remove(bicycle); // Removed bicyclegarage.remove(truck); // Could not remove truckgarage.print(); // Vehicles: car

Page 116: Prototypal inheritance in JavaScript

Higher-order functions & collections

// Encapsulating iterationfunction each(data, callback) {for (var i = 0; i < data.length; i += 1) {callback(data[i]);

}}

// Mapping each value to a resultfunction map(data, operation) {var result = [];each(data, function(value) {result.push(operation(value));

});return result;

}

// Collecting only values satisfying the predicatefunction filter(data, predicate) {var result = [];each(data, function(value) {if (predicate(value)) {result.push(value);

}});return result;

}

// Example

function increment(x) {return x + 1;

}

function odd(x) {return x % 2 === 1;

}

var data = [0, 1, 2, 3, 4];

console.log(map(data, increment)); // [1, 2, 3, 4, 5]console.log(filter(data, odd)); // [1, 3]

Page 117: Prototypal inheritance in JavaScript

Higher-order functions & compositionfunction compose (f, g) {// Receive function arguments and/or return a function as the resultreturn function (x) {return f(g(x));

};}

// Example

function increment (x) {return x + 1;

}

function times2 (x) {return 2 * x;

}

var f = compose(increment, times2);

console.log(f(1)); // 3console.log(f(2)); // 5console.log(f(3)); // 7

Page 118: Prototypal inheritance in JavaScript

Memoization// Without memoization, the function may repeatedly// compute the result for the same argumentsvar fibonacciSlow = function fib (n) {var result;if (n < 2) {result = n;

} else {result = fib(n - 1) + fib(n - 2);console.log('fibSlow(' + n + ') = ' + result);

}return result;

};

// Example

fibonacciSlow(5);// fibSlow(2) = 1// fibSlow(3) = 2// fibSlow(2) = 1// fibSlow(4) = 3// fibSlow(2) = 1// fibSlow(3) = 2// fibSlow(5) = 5

var fibonacci = (function () {// Function keeps previously computed values in its private closure// and returns the cached results when they are availablevar memo = [0, 1];return function fib (n) {var result = memo[n];if (typeof result !== 'number') {result = fib(n - 1) + fib(n - 2);console.log('fib(' + n + ') = ' + result);memo[n] = result;

}return result;

};}());

// Example

fibonacci(5);// fib(2) = 1// fib(3) = 2// fib(4) = 3// fib(5) = 5

Page 119: Prototypal inheritance in JavaScript

Currying and partial function applicationfunction curry (f) {var slice = Array.prototype.slice;var concat = Array.prototype.concat;// Return the curried function f. The returned function is a "named// anonymous function" or more precisely a named function expression.// On the outside, the function is anonymous and its identifier 'curried'// is accessible only from the inside of the functionreturn function curried () {if (f.length > arguments.length) {// If some arguments are still missing, save the supplied arguments// and return a new function delegating back to this function, but// with the additional arguments concatenated to the saved argsvar args = slice.apply(arguments);return function () {return curried.apply(null, concat.apply(args, arguments));

};}// If the sufficient number of arguments is supplied, delegate to freturn f.apply(null, arguments);

};}

// Example

function sum3 (a, b, c) {return a + b + c;

}

s = curry(sum3);

console.log(s(1)(2)(3)); // 6console.log(s(1)(2,3)); // 6console.log(s(1,2)(3)); // 6console.log(s(1,2,3)); // 6