SlideShare a Scribd company logo
Prototypal inheritance
in JavaScript
#JavaScript #Prototype #Inheritance
Miroslav Obradović
m.obradovic@youngculture.com
http://www.youngculture.com
Object is not a primitive
{
name: 'John Doe',
married: false,
age: 25,
};
var person = console.log(person.name); // John Doe
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
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
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
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;
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;
Theory of strings?!
Theory of strings?!
var obj = {};
obj[null] = 42;
console.log(obj.hasOwnProperty('null'));
// true
console.log(obj['null']);
// 42
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
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
null vs. undefined
console.log(typeof null === 'object'); // true
console.log(typeof undefined === 'undefined'); // true
null vs. undefined
console.log(typeof null === 'object'); // true
console.log(typeof undefined === 'undefined'); // true
var n;
console.log(n);
// undefined
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
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
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
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
Inheriting from another object
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
null
Inheriting from another object
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
null
console.log(joe.age);
// 25
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
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
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
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
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
Hide and seek!
{
name: 'Joe'
};
var joe = {
age: 21,
weight: 82,
favorites: {
car: 'yugo'
}
};
null
Hide and seek!
{
name: 'Joe'
};
var joe = {
age: 21,
weight: 82,
favorites: {
car: 'yugo'
}
};
null
console.log(joe.age); // 21
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
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
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
Bound in prototype chains?
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
null
Bound in prototype chains?
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
{
height: 185
};
null
Bound in prototype chains?
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
{
height: 185
};
[[Prototype]] & _ _proto_ _
[[Prototype]] & _ _proto_ _
null
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
[[Prototype]]
_ _proto_ _
[[Prototype]] & _ _proto_ _
null
{
name: 'Joe',
age: 25
};
var joe = {
age: 21,
weight: 82
};
[[Prototype]]
_ _proto_ _
console.log(joe.age);
// 25
[[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
[[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
prototype property
var F = function () {};
prototype property
var F = function () {};
__proto__
function () {};
{
length: 0,
prototype
}
var F =
…
_ _proto_ _
{
constructor: F
}
…
prototype property
console.log(typeof F);
// function
var F = function () {};
__proto__
function () {};
{
length: 0,
prototype
}
var F =
…
_ _proto_ _
{
constructor: F
}
…
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
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
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
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
prototype property & operator new
var F = function () {};
prototype property & operator new
var F = function () {};
_ _proto_ _
{
constructor: F
}
__proto__
function () {};
{
length: 0,
prototype
}
var F =
……
prototype property & operator new
var F = function () {};
_ _proto_ _
{
constructor: F
}
__proto__
function () {};
{
length: 0,
prototype
}
var F =
……
var o = new F();
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();
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();
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();
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();
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();
prototype property & operator new
var F = function (val) {
this.val = val;
};
prototype property & operator new
var F = function (val) {
this.val = val;
};
{
constructor: F
}
function (val) {
this.val = val;
};
{
prototype
}
var F =
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);
};
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);
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 =
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
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);
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 =
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
WTF is this?
WTF is this?
var f = function (args) {
console.log(this);
};
var obj = { m: f };
var array = [ f ];
WTF is this?
var f = function (args) {
console.log(this);
};
var obj = { m: f };
var array = [ f ];
new f(args); // new object
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
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
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
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)
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)
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)
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)
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)
Something in return?
Something in return?
var f = function () {
return; // or w/o return
};
Something in return?
var f = function () {
return; // or w/o return
};
new f(); // new object
f(); // undefined
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;
};
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;
};
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;
};
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;
};
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;
};
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;
};
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;
};
Inherit from that
function create (that) {
}
var newObj = create(that);
Inherit from that
function create (that) {
}
var newObj = create(that);
var F = function () {};
return new F();
Inherit from that
function create (that) {
}
var newObj = create(that);
var F = function () {};
return new F();
{
constructor: F
}
function () {};
{
prototype
}
var F =
Inherit from that
function create (that) {
}
var newObj = create(that);
var F = function () {};
return new F();
{
constructor: F
}
function () {};
{
prototype
}
var F =
var that = {
…
}
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;
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;
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;
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;
instanceof
console.log(objX instanceof F);
instanceof
{
}
var objX =
console.log(objX instanceof F);
instanceof
{
constructor: F
}
function () {};
{
prototype
}
var F =
{
}
var objX =
console.log(objX instanceof F);
instanceof
{
constructor: F
}
function () {};
{
prototype
}
var F =
{
}
var objX =
console.log(objX instanceof F); // true
instanceof
{
constructor: F
}
function () {};
{
prototype
}
var F =
{
}
var objX =
console.log(objX instanceof F);
{
}
var objY =
console.log(objY instanceof F);
// true
instanceof
{
constructor: F
}
function () {};
{
prototype
}
var F =
{
}
var objX =
console.log(objX instanceof F);
{
}
var objY =
console.log(objY instanceof F);
// true
// true
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
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
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
Chicken or the egg?
Chicken or the egg?
console.log(Function instanceof Object); // true
Chicken or the egg?
console.log(Object instanceof Function); // true
console.log(Function instanceof Object); // true
Chicken or the egg?
function Function () {
[native code]
}
prototype
_ _proto_ _
function () {}
constructor
_ _proto_ _ …
Chicken or the egg?
function Object () {
[native code]
}
prototype
_ _proto_ _
{}
constructor
_ _proto_ _ = null…
Chicken or the egg?
function Object () {
[native code]
}
prototype
_ _proto_ _
{}
constructor
_ _proto_ _ = null
function Function () {
[native code]
}
prototype
_ _proto_ _
function () {}
constructor
_ _proto_ _
function Object () {
[native code]
}
prototype
_ _proto_ _
{}
constructor
_ _proto_ _ = null
function Function () {
[native code]
}
prototype
_ _proto_ _
function () {}
constructor
_ _proto_ _
new Object()
_ _proto_ _
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_ _
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_ _
• 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
Thank you!
Q & A
BONUS
Overview of object oriented
and functional concepts,
with examples
Polymorphism – Inheritance
// Base class providing common interface to all subclasses
var 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 interface
var Car = function (doors) {
this.superConstructor('car', 4);
this.doors = doors;
};
// Inherit the base class and keep a reference to the super class constructor
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.superConstructor = Vehicle;
// Specialized subclass methods
Car.prototype.checkDoors = function () {
console.log('This ' + this.name + ' has ' + this.doors + ' doors');
};
// Another subclass sharing the common interface
var Bicycle = function () {
this.superConstructor('bicycle', 2);
};
// Inherit the base class and keep a reference to the super class constructor
Bicycle.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 doors
car.drive(); // Driving the car on 4 wheels
bicycle.drive(); // Driving the bicycle on 2 wheels
Polymorphism – Overloading
// Behavior depends on the number of supplied arguments
var argumentCounter = function() {
if (arguments.length <= 1) {
console.log('Processing at most one argument');
} else {
console.log('Processing multiple arguments');
}
};
// Behavior depends on the argument types
var 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 argument
argumentCounter(1, 2, 3); // Processing multiple arguments
typeChecker('test'); // Processing a string argument
typeChecker(true); // Processing a non-string argument
Encapsulation
var 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
Aggregation
var 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 car
garage.add(bicycle); // Added bicycle
garage.print(); // Vehicles: car, bicycle
garage.remove(bicycle); // Removed bicycle
garage.remove(truck); // Could not remove truck
garage.print(); // Vehicles: car
Higher-order functions & collections
// Encapsulating iteration
function each(data, callback) {
for (var i = 0; i < data.length; i += 1) {
callback(data[i]);
}
}
// Mapping each value to a result
function map(data, operation) {
var result = [];
each(data, function(value) {
result.push(operation(value));
});
return result;
}
// Collecting only values satisfying the predicate
function 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]
Higher-order functions & composition
function compose (f, g) {
// Receive function arguments and/or return a function as the result
return 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)); // 3
console.log(f(2)); // 5
console.log(f(3)); // 7
Memoization
// Without memoization, the function may repeatedly
// compute the result for the same arguments
var 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 available
var 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
Currying and partial function application
function 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 function
return 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 args
var args = slice.apply(arguments);
return function () {
return curried.apply(null, concat.apply(args, arguments));
};
}
// If the sufficient number of arguments is supplied, delegate to f
return f.apply(null, arguments);
};
}
// Example
function sum3 (a, b, c) {
return a + b + c;
}
s = curry(sum3);
console.log(s(1)(2)(3)); // 6
console.log(s(1)(2,3)); // 6
console.log(s(1,2)(3)); // 6
console.log(s(1,2,3)); // 6

More Related Content

What's hot

JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
Jarrod Overson
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
Nikita Popov
 
start_printf: dev/ic/com.c comstart()
start_printf: dev/ic/com.c comstart()start_printf: dev/ic/com.c comstart()
start_printf: dev/ic/com.c comstart()
Kiwamu Okabe
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
David Atchley
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
Todd Anglin
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8
Wilson Su
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
Masahiro Honma
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
corehard_by
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
Attila Balazs
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
Jorn Oomen
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
Workhorse Computing
 
Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)
Oky Firmansyah
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
Jarrod Overson
 
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
Felipe Prado
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Mirah Talk for Boulder Ruby Group
Mirah Talk for Boulder Ruby GroupMirah Talk for Boulder Ruby Group
Mirah Talk for Boulder Ruby Group
baroquebobcat
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
Stephen Vance
 

What's hot (20)

JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
start_printf: dev/ic/com.c comstart()
start_printf: dev/ic/com.c comstart()start_printf: dev/ic/com.c comstart()
start_printf: dev/ic/com.c comstart()
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
 
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Mirah Talk for Boulder Ruby Group
Mirah Talk for Boulder Ruby GroupMirah Talk for Boulder Ruby Group
Mirah Talk for Boulder Ruby Group
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
 

Similar to Prototypal inheritance in JavaScript

Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
Bedis ElAchèche
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
Tomasz Dziuda
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
Object oriented javascript
Object oriented javascriptObject oriented javascript
Object oriented javascript
Shah Jalal
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
Giordano Scalzo
 
Es.next
Es.nextEs.next
Es.next
Ignacio Gil
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
Anders Jönsson
 
ts+js
ts+jsts+js
js+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdfjs+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdf
NuttavutThongjor1
 
fullstack typescript with react and express.pdf
fullstack typescript with react and express.pdffullstack typescript with react and express.pdf
fullstack typescript with react and express.pdf
NuttavutThongjor1
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
Visual Engineering
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
Manoj Kumar
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
ryanstout
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
Santosh Wadghule
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action script
Christophe Herreman
 
ECMAScript 6 new features
ECMAScript 6 new featuresECMAScript 6 new features
ECMAScript 6 new features
GephenSG
 
Adding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer ToolboxAdding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer Toolbox
Jeff Strauss
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
Andrew Eddie
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
Giovanni Scerra ☃
 

Similar to Prototypal inheritance in JavaScript (20)

Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Object oriented javascript
Object oriented javascriptObject oriented javascript
Object oriented javascript
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
 
Es.next
Es.nextEs.next
Es.next
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
 
ts+js
ts+jsts+js
ts+js
 
js+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdfjs+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdf
 
fullstack typescript with react and express.pdf
fullstack typescript with react and express.pdffullstack typescript with react and express.pdf
fullstack typescript with react and express.pdf
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action script
 
ECMAScript 6 new features
ECMAScript 6 new featuresECMAScript 6 new features
ECMAScript 6 new features
 
Adding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer ToolboxAdding ES6 to Your Developer Toolbox
Adding ES6 to Your Developer Toolbox
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 

Recently uploaded

Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Undress Baby
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
Peter Muessig
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
aymanquadri279
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 

Recently uploaded (20)

Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling ExtensionsUI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
UI5con 2024 - Boost Your Development Experience with UI5 Tooling Extensions
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 

Prototypal inheritance in JavaScript

  • 1. Prototypal inheritance in JavaScript #JavaScript #Prototype #Inheritance Miroslav Obradović m.obradovic@youngculture.com http://www.youngculture.com
  • 2. Object is not a primitive { name: 'John Doe', married: false, age: 25, }; var person = console.log(person.name); // John Doe
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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;
  • 7. 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;
  • 9. Theory of strings?! var obj = {}; obj[null] = 42; console.log(obj.hasOwnProperty('null')); // true console.log(obj['null']); // 42
  • 10. 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
  • 11. 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
  • 12. null vs. undefined console.log(typeof null === 'object'); // true console.log(typeof undefined === 'undefined'); // true
  • 13. null vs. undefined console.log(typeof null === 'object'); // true console.log(typeof undefined === 'undefined'); // true var n; console.log(n); // undefined
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. Inheriting from another object { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; null
  • 19. Inheriting from another object { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; null console.log(joe.age); // 25
  • 20. 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
  • 21. 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
  • 22. 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
  • 23. 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
  • 24. 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
  • 25. Hide and seek! { name: 'Joe' }; var joe = { age: 21, weight: 82, favorites: { car: 'yugo' } }; null
  • 26. Hide and seek! { name: 'Joe' }; var joe = { age: 21, weight: 82, favorites: { car: 'yugo' } }; null console.log(joe.age); // 21
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. Bound in prototype chains? { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; null
  • 31. Bound in prototype chains? { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; { height: 185 }; null
  • 32. Bound in prototype chains? { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; { height: 185 };
  • 33. [[Prototype]] & _ _proto_ _
  • 34. [[Prototype]] & _ _proto_ _ null { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; [[Prototype]] _ _proto_ _
  • 35. [[Prototype]] & _ _proto_ _ null { name: 'Joe', age: 25 }; var joe = { age: 21, weight: 82 }; [[Prototype]] _ _proto_ _ console.log(joe.age); // 25
  • 36. [[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
  • 37. [[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
  • 38. prototype property var F = function () {};
  • 39. prototype property var F = function () {}; __proto__ function () {}; { length: 0, prototype } var F = … _ _proto_ _ { constructor: F } …
  • 40. prototype property console.log(typeof F); // function var F = function () {}; __proto__ function () {}; { length: 0, prototype } var F = … _ _proto_ _ { constructor: F } …
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. prototype property & operator new var F = function () {};
  • 46. prototype property & operator new var F = function () {}; _ _proto_ _ { constructor: F } __proto__ function () {}; { length: 0, prototype } var F = ……
  • 47. prototype property & operator new var F = function () {}; _ _proto_ _ { constructor: F } __proto__ function () {}; { length: 0, prototype } var F = …… var o = new F();
  • 48. 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();
  • 49. 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();
  • 50. 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();
  • 51. 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();
  • 52. 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();
  • 53. prototype property & operator new var F = function (val) { this.val = val; };
  • 54. prototype property & operator new var F = function (val) { this.val = val; }; { constructor: F } function (val) { this.val = val; }; { prototype } var F =
  • 55. 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); };
  • 56. 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);
  • 57. 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 =
  • 58. 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
  • 59. 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);
  • 60. 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 =
  • 61. 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
  • 63. WTF is this? var f = function (args) { console.log(this); }; var obj = { m: f }; var array = [ f ];
  • 64. WTF is this? var f = function (args) { console.log(this); }; var obj = { m: f }; var array = [ f ]; new f(args); // new object
  • 65. 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
  • 66. 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
  • 67. 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
  • 68. 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)
  • 69. 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)
  • 70. 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)
  • 71. 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)
  • 72. 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)
  • 74. Something in return? var f = function () { return; // or w/o return };
  • 75. Something in return? var f = function () { return; // or w/o return }; new f(); // new object f(); // undefined
  • 76. 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; };
  • 77. 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; };
  • 78. 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; };
  • 79. 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; };
  • 80. 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; };
  • 81. 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; };
  • 82. 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; };
  • 83. Inherit from that function create (that) { } var newObj = create(that);
  • 84. Inherit from that function create (that) { } var newObj = create(that); var F = function () {}; return new F();
  • 85. Inherit from that function create (that) { } var newObj = create(that); var F = function () {}; return new F(); { constructor: F } function () {}; { prototype } var F =
  • 86. Inherit from that function create (that) { } var newObj = create(that); var F = function () {}; return new F(); { constructor: F } function () {}; { prototype } var F = var that = { … }
  • 87. 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;
  • 88. 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;
  • 89. 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;
  • 90. 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;
  • 93. instanceof { constructor: F } function () {}; { prototype } var F = { } var objX = console.log(objX instanceof F);
  • 94. instanceof { constructor: F } function () {}; { prototype } var F = { } var objX = console.log(objX instanceof F); // true
  • 95. instanceof { constructor: F } function () {}; { prototype } var F = { } var objX = console.log(objX instanceof F); { } var objY = console.log(objY instanceof F); // true
  • 96. instanceof { constructor: F } function () {}; { prototype } var F = { } var objX = console.log(objX instanceof F); { } var objY = console.log(objY instanceof F); // true // true
  • 97. 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
  • 98. 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
  • 99. 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
  • 100. Chicken or the egg?
  • 101. Chicken or the egg? console.log(Function instanceof Object); // true
  • 102. Chicken or the egg? console.log(Object instanceof Function); // true console.log(Function instanceof Object); // true
  • 103. Chicken or the egg? function Function () { [native code] } prototype _ _proto_ _ function () {} constructor _ _proto_ _ …
  • 104. Chicken or the egg? function Object () { [native code] } prototype _ _proto_ _ {} constructor _ _proto_ _ = null…
  • 105. Chicken or the egg? function Object () { [native code] } prototype _ _proto_ _ {} constructor _ _proto_ _ = null function Function () { [native code] } prototype _ _proto_ _ function () {} constructor _ _proto_ _
  • 106. function Object () { [native code] } prototype _ _proto_ _ {} constructor _ _proto_ _ = null function Function () { [native code] } prototype _ _proto_ _ function () {} constructor _ _proto_ _ new Object() _ _proto_ _
  • 107. 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_ _
  • 108. 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_ _
  • 109. • 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
  • 111. BONUS Overview of object oriented and functional concepts, with examples
  • 112. Polymorphism – Inheritance // Base class providing common interface to all subclasses var 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 interface var Car = function (doors) { this.superConstructor('car', 4); this.doors = doors; }; // Inherit the base class and keep a reference to the super class constructor Car.prototype = Object.create(Vehicle.prototype); Car.prototype.superConstructor = Vehicle; // Specialized subclass methods Car.prototype.checkDoors = function () { console.log('This ' + this.name + ' has ' + this.doors + ' doors'); }; // Another subclass sharing the common interface var Bicycle = function () { this.superConstructor('bicycle', 2); }; // Inherit the base class and keep a reference to the super class constructor Bicycle.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 doors car.drive(); // Driving the car on 4 wheels bicycle.drive(); // Driving the bicycle on 2 wheels
  • 113. Polymorphism – Overloading // Behavior depends on the number of supplied arguments var argumentCounter = function() { if (arguments.length <= 1) { console.log('Processing at most one argument'); } else { console.log('Processing multiple arguments'); } }; // Behavior depends on the argument types var 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 argument argumentCounter(1, 2, 3); // Processing multiple arguments typeChecker('test'); // Processing a string argument typeChecker(true); // Processing a non-string argument
  • 114. Encapsulation var 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
  • 115. Aggregation var 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 car garage.add(bicycle); // Added bicycle garage.print(); // Vehicles: car, bicycle garage.remove(bicycle); // Removed bicycle garage.remove(truck); // Could not remove truck garage.print(); // Vehicles: car
  • 116. Higher-order functions & collections // Encapsulating iteration function each(data, callback) { for (var i = 0; i < data.length; i += 1) { callback(data[i]); } } // Mapping each value to a result function map(data, operation) { var result = []; each(data, function(value) { result.push(operation(value)); }); return result; } // Collecting only values satisfying the predicate function 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]
  • 117. Higher-order functions & composition function compose (f, g) { // Receive function arguments and/or return a function as the result return 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)); // 3 console.log(f(2)); // 5 console.log(f(3)); // 7
  • 118. Memoization // Without memoization, the function may repeatedly // compute the result for the same arguments var 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 available var 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
  • 119. Currying and partial function application function 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 function return 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 args var args = slice.apply(arguments); return function () { return curried.apply(null, concat.apply(args, arguments)); }; } // If the sufficient number of arguments is supplied, delegate to f return f.apply(null, arguments); }; } // Example function sum3 (a, b, c) { return a + b + c; } s = curry(sum3); console.log(s(1)(2)(3)); // 6 console.log(s(1)(2,3)); // 6 console.log(s(1,2)(3)); // 6 console.log(s(1,2,3)); // 6