KEMBAR78
Let's JavaScript | PDF
Let's
JavaScript
(Not any other
programming
language)

by Pawel Dorofiejczyk
Java... what !?
"Java is to JavaScript like car is to carpet"
● Object Oriented
● Dynamic and lose typed
● No classes, no interfaces, no
abstraction
● Prototypical inheritance
● No privacy control at object level
● Object as collection of properties
● Function scope
LOL! Who use that crap !?
● Websites frontend
● Server Side JavaScript (node.js, Rhino)
● Document oriented databases: MongoDB,
CouchDB
● Windows 8 (WinJS)
● GNOME Shell
● OpenOffice and Adobe Creative Suite
(Photoshop, Illustrator, Dreamwaver)
● Adobe AIR
and more...
Let's start brainwashing!
Let's create a variable
var name = "Let's JavaScript"; //string
var i = 1; //number ("integer")
var fl = 1.11; //number ("float")
var boo = true; //boolean
glob = "I'm global string";
JavaScript's variable
Local variable declaration by var
keyword
● Global variable declaration - without
var (don't use it!)
● Dynamic type
●
Variable types
primitives

objects

special

Number

Object

Null

Function

String

Array
Date

Boolean

RegExp

Undefined
typeof - the crap?
typeof "string var"; //returns "string";
typeof 1; //returns "number";
typeof {}; //returns "object";
typeof undefined; //returns "undefined";
typeof function(){}; //returns "function"
But...
typeof []; //returns "object" (!)
typeof null; //returns "object" (!!!)
typeof NaN; // returns "number" ;)
Let's create a function

var f = function(arg) {
//function body
};
Function in JavaScript
●
●
●
●
●
●
●
●

Is an object
Can have properties and methods
Is Closure
Reference can be stored in variable
Can create other functions
Have own scope
Have special property - prototype
Native methods bind, apply, call
So...
function hello() {
console.log('Hello world');

Looks like "normal" function declaration,
but in fact...

}

===
var hello = function() {
console.log('Hello world');
}

...it is translated to this form so
anonymous function is created and it's
reference is passed to var

===

var hello = new Function(
"console.log('Hello world')"
);

and what's more every function
declaration is creation of new object
Function arguments
● Are stored in pseudo-array arguments
● Primitives (number, string, boolean) are
always passed by value
● Objects are passed by reference
Function arguments
var test = function(a, b, obj) {
obj.modified = true;
console.log(arguments);
}
var obj = {};
console.log(obj.modified); //'undefined'
test(1, 'a', obj); //{ '0': 1, '1': 'a', '2': { modified: true } }
console.log(obj.modified); //true
It is object so was passed
by reference
Accumulator problem
Problem :
"I want to create accumulator function which
accumulates values passed to it"
Solution:
"In JavaScript, function is an object so I can
create function with internal variable handling
passed values sum"
How to do NOT use function
var accumulator = function(x) {
this.sum = (this.sum || 0) + x;
return this.sum;
}
console.log(accumulator(1)); //1
console.log(accumulator(1)); //2
console.log(accumulator.sum); //undefined
console.log(sum); //2
//whoups!
this IS NOT this ?!
this IS NOT this
this by default refers to the object that a
function is a member of

{
var accumulator = function(x) {
this.sum = (this.sum || 0) + x;
return this.sum;
}
}

In this case, function is member of
default global object so this refers to
global object.
If we run this code in browser, global
object is window so this === window
Let’s try without this
var accumulator = function(x) {
accumulator.sum = (accumulator.sum || 0) + x;
return accumulator.sum;
}
Public, so someone can spoil our
internal state

Ok… but...
accumulator.sum = undefined;
accumulator(1); //returns NaN :(
Scope, the ultimate!*

*Function is the ultimate but without scope, function is nothing
Let's create a scope

var f = function() {
//new scope :)
};

looks familiar?
or in other way...

(function() {
//new scope
}());
JavaScript's scope
● Is static (lexical)
● Is created only by function
● Function arguments becomes part of
scope
● Child scope have reference to parent
scope (scope chain)
● this is not scope (!!!)
Function scope
var test = 'global scope var';
var f = function() {
var test = 'function f scope';
console.log(test);
}

Local test variable declaration,
covers global test variable

console.log(test); //returns 'global scope var'
f(); //returns 'function f scope'
Hidden scope reference
var test = 'global scope var';
var a = function() {
console.log(test);
}
var b = function(callback) {
var test = 'function b scope var';
callback();
}
b(a); //returns 'global scope var'

Function object
contains hidden
reference to scope in
which was created
Hidden scope reference
var test = 5;
var inc = function() {
return ++test;
}
var dec = function() {
return --test;
}
inc(); //returns 6
dec(); //returns 5 NOT 4

Both functions inc
and dec have
reference to common
scope so both can
modify the same
variable
Returning to accumulator problem
"Creator" function

var accumulator = (function() {
Initialize sum variable in
var sum = 0;
creator function's scope
return function(x) {
Adds x to parent scope's
sum += x;
variable sum
return sum;
};
})();
Immediate executing

Scope based privacy!
Common scoping mistake
var callbacks = [];
for(var i = 0; i < 10; i++) {
callbacks[i] = function() {
console.log(i);
}
}
for(var index in callbacks) {
callbacks[index]();
}
Common scoping mistake
var callbacks = [];
for(var i = 0; i < 10; i++) {
callbacks[i] = function() {
console.log(i);
}
At the end of for loop, i === 10
}
for(var index in callbacks) {
callbacks[index]();
}

For loop doesn't create
new scope, so variable i is
global

Log global variable i
.bind for the rescue!

bind is Function object method which
creates new function with bounded
parameters
.bind for the rescue!
var log = function(x) {
console.log(x);
}

Object reference which
will be bound to this
variable in function
scope (It doesn't matter
in this case)

var logHello = log.bind(null, ”Hello”);
log(1); //prints 1
log(”test”); //prints test
logHello(); //prints Hello

Values which will be
bound to function’s
parameters
Common scoping mistake FIXED
var callbacks = [];
var logger = function(i) {
console.log(i);
}

Create local scope
variable i
Log logger function's
scope variable i

for(var i = 0; i < 10; i++) {
callbacks[i] = logger.bind(null, i);
}
Returns new function with bounded
global variable i value as function
argument
Let's create an object

var obj = {};
B-B-B-B-But... Where is the
class?!
Object-oriented, NOT Class-oriented
Java

JavaScript

class HelloWorld {
public void greet() {
System.out.println('Hello!');
}
}

var obj = {
greet: function() {
console.log('Hello');
}
}

HelloWorld obj = new HelloWorld();
obj.greet()

obj.greet();
JavaScript Object
●
●
●
●
●
●
●
●
●

Dynamic, not ordered, key-value
Collection of properties
Array access or object access
Iterable
Created in runtime
Object literal {}
No privacy control at object level
Prototypical inheritance
Constructor functions
MOAR objects!
Simple objects
var obj = {
prop1: 'test' //add property at creation time
}
obj.prop2 = function() { //add property later
console.log(this.prop1);
}
console.log(obj.prop1 == obj['prop1']); //returns true
obj['prop2'](); //returns 'test'
Iterate objects
var obj = {
prop1: 'test1',
prop2: 'test2',
prop3: function(){}
}
for(var prop in obj) {
console.log(obj[prop]);
}

Returns:
'test1'
'test2'
[Function]
OR
'test2'
'test1'
[Function]
OR
...
Iterate objects
var obj = {
prop1: 'test1',
prop2: 'test2',
prop3: function(){}
}
for(var prop in obj) {
console.log(obj[prop]);
}

IT DOESN'T GUARANTEE
ORDER!!!
Constructors in JavaScript

Constructor is not magic object method.
It's a function which returns new objects.
Constructors in JavaScript
Java

JavaScript

class HelloWorld {
private String greetMsg;

function HelloWorld(greetMsg) {
return {
greet: function() {
console.log(greetMsg);
}
}
}

public HelloWorld(String greetMsg) {
this.greetMsg = greetMsg;
}
public void greet() {
System.out.println(this.greetMsg);
}
}
HelloWorld hi = new HelloWorld('Hi!');
obj.greet();

var hi = HelloWorld('Hi!');
hi.greet();
new and prototype
How new works
Have to be used with constructor
function
● Uses prototype function property
reference as __proto__ of new object
● Binds new object to constructor's this
● Executes constructor function
●
How new works
var HelloWorld = function(greetMsg) {
this.greetMsg = greetMsg;
Don't use return. New
object will be returned
automatically

}

HelloWorld.prototype.greet = function() {
console.log(this.greetMsg);
}
var hi = new HelloWorld('Hi!');
hi.greet();

We create our constructor
as new function object

this is binded to new object so
we declare object variable
greetMsg

We declare common object's
properties in constructor
function's prototype
How new works
HelloWorld.prototype
● greet

HelloWorld
● prototype

hi
●

__proto__

hello
● __proto__

*Imagine __proto__ is hidden reference (it is available in some browsers but It is not standard)
How new works
var HelloWorld = function(greetMsg) {
this.greetMsg = greetMsg;
Don't use return. New
object will be returned
automatically

}

HelloWorld.prototype.greet = function() {
console.log(this.greetMsg);
}
var hi = new HelloWorld('Hi!');
hi.greet();
console.log(hi.greetMsg); //returns 'Hi!'

We create our constructor
as new function object

this is binded to new object so
we declare object variable
greetMsg

We declare common object's
properties in constructor
function's prototype
Privacy problem - how to do NOT fix
var HelloWorld = function(greetMsg) {
}
HelloWorld.prototype.greet = function() {
console.log(greetMsg);
}

We would like to keep greetMsg
private. As we know, the only
way is to do it private in
constructor's scope

We are trying to get private
variable but it is different scope
which don't have access to
constructor's scope

var hi = new HelloWorld('Hi!');
hi.greet(); //ReferenceError: greetMsg is not defined
Privacy problem fix
var HelloWorld = function(greetMsg) {
this.greet = function() {

We creating greet function
inside constructor so it has
access to constructor's scope.

console.log(greetMsg);
}
}

Consider that it is not part of
prototype so we create new
function per object creation.
In JavaScript, memory is price
for privacy.

var hi = new HelloWorld('Hi!');
hi.greet();
console.log(hi.greetMsg); //returns 'undefined'
Forgotten new disaster
var HelloWorld = function(greetMsg) {
this.greetMsg = greetMsg;
}

this is binded to global object
so we declare global variable
greetMsg

HelloWorld.prototype.greet = function() {
console.log(this.greetMsg);

Prototype won't be used, so
we won't have greet method

}
Disaster begins here

var hi = HelloWorld('Hi!');
hi.greet(); //TypeError: Cannot call method 'greet' of undefined
console.log(greetMsg); //returns 'Hi!'
Your application has just been blown up

Do you still like new?
Classical inheritance
var Animal = function(name) {
this.name = name;
}
Animal.prototype.getName = function() {
return this.name;
}
var dolphin = new Animal('Dolphin');
dolphin.getName(); //returns 'Dolphin'
Classical inheritance
We want WalkingAnimal, which extends Animal and
adds method walk
var WalkingAnimal = function() {
}

We need constructor
function

WalkingAnimal.prototype = new Animal();
We have to set object we would like to extend as
constructor prototype.
Unfortunately we have to call constructor to create
object. We don't pass any arguments so name will be
undefined
Classical inheritance
var WalkingAnimal = function(name) {
We should not forget
Animal.call(this, name);
about calling Animal
constructor to do it's job
}
WalkingAnimal.prototype = new Animal();
WalkingAnimal.prototype.walk = function() {
console.log(this.getName() + 'is walking');
Next we add method walk
}
to WalkingAnimal
prototype

var cow = new WalkingAnimal('Cow');
cow.getName(); //returns 'Cow'
cow.walk(); //'Cow is walking'
Looks ugly?
Object.create*
var WalkingAnimal = function(name) {
Animal.call(this, name);
}
WalkingAnimal.prototype = Object.create(Animal.prototype);
WalkingAnimal.prototype.walk = function() {
console.log(this.getName() + ' is walking');
}
Object.create sets hidden __proto__
reference to Animal.prototype but
without calling constructor

*Introduced in JavaScript 1.6
inherits function to hide ugly stuff
Function.prototype.inherits = function(parent, methods) {
this.prototype = Object.create(parent.prototype);
We store parent in
this.prototype.$parent = parent;
$parent variable. Can
be useful later
for(name in methods) {
this.prototype[name] = methods[name];
}
}
We copy every method from methods
object to function prototype
inherits method usage
var WalkingAnimal = function(name) {
this.$parent.call(this, name);
}
WalkingAnimal.inherits(Animal, {
walk: function() {
console.log(this.getName() + 'is walking');
}
}
Or maybe don't do it classical
●
●
●
●
●

Don't use new
Don't use prototype
Forgot about inheritance tree
Use composition and mixins
Use power of functions (including functional
programming)

● Treat objects like function namespace or data container
not state container

● Occasionally use Object.create and Object.
defineProperty if you need
References
●

Douglas Crockford "JavaScript: The good parts"

●

Douglas Crockford's site (http://www.crockford.com/)

●

Dymitry Soshnikov's blog (http://dmitrysoshnikov.com)

●

Mozilla's "A re-introduction to JavaScript" (https://developer.mozilla.org/enUS/docs/JavaScript/A_re-introduction_to_JavaScript?redirect=no)

●

Angus Croll's blog (http://javascriptweblog.wordpress.com)
Questions?
Want more?
Here you are director's cut ;)
JavaScript primitives with methods?
var a = 1;
console.log(typeof a); //returns 'number'
console.log(a instanceof Number); //returns false
console.log(a.toExponential()); //returns 1e+0
var b = "abc";
console.log(typeof b); //returns 'string'
console.log(b instanceof String); //returns false
console.log(b.slice(1)); //returns 'bc'
var c = true;
console.log(typeof c); //returns 'boolean'
console.log(c instanceof Boolean); //returns false
console.log(c.toString()); //returns 'true'
The secret life of primitives

var a = 1;
a.toExponential();

It is not really method
of primitive.

=

var a = 1;
(new Number(a)).toExponential();

Every time you trying access
primitive method, new object,
containing primitive value is
created secretly.

Let's JavaScript

  • 1.
  • 2.
    Java... what !? "Javais to JavaScript like car is to carpet"
  • 3.
    ● Object Oriented ●Dynamic and lose typed ● No classes, no interfaces, no abstraction ● Prototypical inheritance ● No privacy control at object level ● Object as collection of properties ● Function scope
  • 4.
    LOL! Who usethat crap !?
  • 5.
    ● Websites frontend ●Server Side JavaScript (node.js, Rhino) ● Document oriented databases: MongoDB, CouchDB ● Windows 8 (WinJS) ● GNOME Shell ● OpenOffice and Adobe Creative Suite (Photoshop, Illustrator, Dreamwaver) ● Adobe AIR and more...
  • 6.
  • 7.
    Let's create avariable var name = "Let's JavaScript"; //string var i = 1; //number ("integer") var fl = 1.11; //number ("float") var boo = true; //boolean glob = "I'm global string";
  • 8.
    JavaScript's variable Local variabledeclaration by var keyword ● Global variable declaration - without var (don't use it!) ● Dynamic type ●
  • 10.
  • 11.
    typeof - thecrap? typeof "string var"; //returns "string"; typeof 1; //returns "number"; typeof {}; //returns "object"; typeof undefined; //returns "undefined"; typeof function(){}; //returns "function" But... typeof []; //returns "object" (!) typeof null; //returns "object" (!!!) typeof NaN; // returns "number" ;)
  • 13.
    Let's create afunction var f = function(arg) { //function body };
  • 15.
    Function in JavaScript ● ● ● ● ● ● ● ● Isan object Can have properties and methods Is Closure Reference can be stored in variable Can create other functions Have own scope Have special property - prototype Native methods bind, apply, call
  • 16.
    So... function hello() { console.log('Helloworld'); Looks like "normal" function declaration, but in fact... } === var hello = function() { console.log('Hello world'); } ...it is translated to this form so anonymous function is created and it's reference is passed to var === var hello = new Function( "console.log('Hello world')" ); and what's more every function declaration is creation of new object
  • 17.
    Function arguments ● Arestored in pseudo-array arguments ● Primitives (number, string, boolean) are always passed by value ● Objects are passed by reference
  • 18.
    Function arguments var test= function(a, b, obj) { obj.modified = true; console.log(arguments); } var obj = {}; console.log(obj.modified); //'undefined' test(1, 'a', obj); //{ '0': 1, '1': 'a', '2': { modified: true } } console.log(obj.modified); //true It is object so was passed by reference
  • 19.
    Accumulator problem Problem : "Iwant to create accumulator function which accumulates values passed to it" Solution: "In JavaScript, function is an object so I can create function with internal variable handling passed values sum"
  • 20.
    How to doNOT use function var accumulator = function(x) { this.sum = (this.sum || 0) + x; return this.sum; } console.log(accumulator(1)); //1 console.log(accumulator(1)); //2 console.log(accumulator.sum); //undefined console.log(sum); //2 //whoups!
  • 21.
    this IS NOTthis ?!
  • 22.
    this IS NOTthis this by default refers to the object that a function is a member of { var accumulator = function(x) { this.sum = (this.sum || 0) + x; return this.sum; } } In this case, function is member of default global object so this refers to global object. If we run this code in browser, global object is window so this === window
  • 23.
    Let’s try withoutthis var accumulator = function(x) { accumulator.sum = (accumulator.sum || 0) + x; return accumulator.sum; } Public, so someone can spoil our internal state Ok… but... accumulator.sum = undefined; accumulator(1); //returns NaN :(
  • 25.
    Scope, the ultimate!* *Functionis the ultimate but without scope, function is nothing
  • 26.
    Let's create ascope var f = function() { //new scope :) }; looks familiar?
  • 27.
    or in otherway... (function() { //new scope }());
  • 28.
    JavaScript's scope ● Isstatic (lexical) ● Is created only by function ● Function arguments becomes part of scope ● Child scope have reference to parent scope (scope chain) ● this is not scope (!!!)
  • 29.
    Function scope var test= 'global scope var'; var f = function() { var test = 'function f scope'; console.log(test); } Local test variable declaration, covers global test variable console.log(test); //returns 'global scope var' f(); //returns 'function f scope'
  • 30.
    Hidden scope reference vartest = 'global scope var'; var a = function() { console.log(test); } var b = function(callback) { var test = 'function b scope var'; callback(); } b(a); //returns 'global scope var' Function object contains hidden reference to scope in which was created
  • 31.
    Hidden scope reference vartest = 5; var inc = function() { return ++test; } var dec = function() { return --test; } inc(); //returns 6 dec(); //returns 5 NOT 4 Both functions inc and dec have reference to common scope so both can modify the same variable
  • 32.
    Returning to accumulatorproblem "Creator" function var accumulator = (function() { Initialize sum variable in var sum = 0; creator function's scope return function(x) { Adds x to parent scope's sum += x; variable sum return sum; }; })(); Immediate executing Scope based privacy!
  • 34.
    Common scoping mistake varcallbacks = []; for(var i = 0; i < 10; i++) { callbacks[i] = function() { console.log(i); } } for(var index in callbacks) { callbacks[index](); }
  • 35.
    Common scoping mistake varcallbacks = []; for(var i = 0; i < 10; i++) { callbacks[i] = function() { console.log(i); } At the end of for loop, i === 10 } for(var index in callbacks) { callbacks[index](); } For loop doesn't create new scope, so variable i is global Log global variable i
  • 36.
    .bind for therescue! bind is Function object method which creates new function with bounded parameters
  • 37.
    .bind for therescue! var log = function(x) { console.log(x); } Object reference which will be bound to this variable in function scope (It doesn't matter in this case) var logHello = log.bind(null, ”Hello”); log(1); //prints 1 log(”test”); //prints test logHello(); //prints Hello Values which will be bound to function’s parameters
  • 38.
    Common scoping mistakeFIXED var callbacks = []; var logger = function(i) { console.log(i); } Create local scope variable i Log logger function's scope variable i for(var i = 0; i < 10; i++) { callbacks[i] = logger.bind(null, i); } Returns new function with bounded global variable i value as function argument
  • 39.
    Let's create anobject var obj = {};
  • 40.
  • 41.
    Object-oriented, NOT Class-oriented Java JavaScript classHelloWorld { public void greet() { System.out.println('Hello!'); } } var obj = { greet: function() { console.log('Hello'); } } HelloWorld obj = new HelloWorld(); obj.greet() obj.greet();
  • 42.
    JavaScript Object ● ● ● ● ● ● ● ● ● Dynamic, notordered, key-value Collection of properties Array access or object access Iterable Created in runtime Object literal {} No privacy control at object level Prototypical inheritance Constructor functions
  • 43.
  • 44.
    Simple objects var obj= { prop1: 'test' //add property at creation time } obj.prop2 = function() { //add property later console.log(this.prop1); } console.log(obj.prop1 == obj['prop1']); //returns true obj['prop2'](); //returns 'test'
  • 45.
    Iterate objects var obj= { prop1: 'test1', prop2: 'test2', prop3: function(){} } for(var prop in obj) { console.log(obj[prop]); } Returns: 'test1' 'test2' [Function] OR 'test2' 'test1' [Function] OR ...
  • 46.
    Iterate objects var obj= { prop1: 'test1', prop2: 'test2', prop3: function(){} } for(var prop in obj) { console.log(obj[prop]); } IT DOESN'T GUARANTEE ORDER!!!
  • 48.
    Constructors in JavaScript Constructoris not magic object method. It's a function which returns new objects.
  • 49.
    Constructors in JavaScript Java JavaScript classHelloWorld { private String greetMsg; function HelloWorld(greetMsg) { return { greet: function() { console.log(greetMsg); } } } public HelloWorld(String greetMsg) { this.greetMsg = greetMsg; } public void greet() { System.out.println(this.greetMsg); } } HelloWorld hi = new HelloWorld('Hi!'); obj.greet(); var hi = HelloWorld('Hi!'); hi.greet();
  • 50.
  • 51.
    How new works Haveto be used with constructor function ● Uses prototype function property reference as __proto__ of new object ● Binds new object to constructor's this ● Executes constructor function ●
  • 52.
    How new works varHelloWorld = function(greetMsg) { this.greetMsg = greetMsg; Don't use return. New object will be returned automatically } HelloWorld.prototype.greet = function() { console.log(this.greetMsg); } var hi = new HelloWorld('Hi!'); hi.greet(); We create our constructor as new function object this is binded to new object so we declare object variable greetMsg We declare common object's properties in constructor function's prototype
  • 53.
    How new works HelloWorld.prototype ●greet HelloWorld ● prototype hi ● __proto__ hello ● __proto__ *Imagine __proto__ is hidden reference (it is available in some browsers but It is not standard)
  • 54.
    How new works varHelloWorld = function(greetMsg) { this.greetMsg = greetMsg; Don't use return. New object will be returned automatically } HelloWorld.prototype.greet = function() { console.log(this.greetMsg); } var hi = new HelloWorld('Hi!'); hi.greet(); console.log(hi.greetMsg); //returns 'Hi!' We create our constructor as new function object this is binded to new object so we declare object variable greetMsg We declare common object's properties in constructor function's prototype
  • 55.
    Privacy problem -how to do NOT fix var HelloWorld = function(greetMsg) { } HelloWorld.prototype.greet = function() { console.log(greetMsg); } We would like to keep greetMsg private. As we know, the only way is to do it private in constructor's scope We are trying to get private variable but it is different scope which don't have access to constructor's scope var hi = new HelloWorld('Hi!'); hi.greet(); //ReferenceError: greetMsg is not defined
  • 56.
    Privacy problem fix varHelloWorld = function(greetMsg) { this.greet = function() { We creating greet function inside constructor so it has access to constructor's scope. console.log(greetMsg); } } Consider that it is not part of prototype so we create new function per object creation. In JavaScript, memory is price for privacy. var hi = new HelloWorld('Hi!'); hi.greet(); console.log(hi.greetMsg); //returns 'undefined'
  • 57.
    Forgotten new disaster varHelloWorld = function(greetMsg) { this.greetMsg = greetMsg; } this is binded to global object so we declare global variable greetMsg HelloWorld.prototype.greet = function() { console.log(this.greetMsg); Prototype won't be used, so we won't have greet method } Disaster begins here var hi = HelloWorld('Hi!'); hi.greet(); //TypeError: Cannot call method 'greet' of undefined console.log(greetMsg); //returns 'Hi!'
  • 58.
    Your application hasjust been blown up Do you still like new?
  • 59.
    Classical inheritance var Animal= function(name) { this.name = name; } Animal.prototype.getName = function() { return this.name; } var dolphin = new Animal('Dolphin'); dolphin.getName(); //returns 'Dolphin'
  • 60.
    Classical inheritance We wantWalkingAnimal, which extends Animal and adds method walk var WalkingAnimal = function() { } We need constructor function WalkingAnimal.prototype = new Animal(); We have to set object we would like to extend as constructor prototype. Unfortunately we have to call constructor to create object. We don't pass any arguments so name will be undefined
  • 61.
    Classical inheritance var WalkingAnimal= function(name) { We should not forget Animal.call(this, name); about calling Animal constructor to do it's job } WalkingAnimal.prototype = new Animal(); WalkingAnimal.prototype.walk = function() { console.log(this.getName() + 'is walking'); Next we add method walk } to WalkingAnimal prototype var cow = new WalkingAnimal('Cow'); cow.getName(); //returns 'Cow' cow.walk(); //'Cow is walking'
  • 62.
  • 63.
    Object.create* var WalkingAnimal =function(name) { Animal.call(this, name); } WalkingAnimal.prototype = Object.create(Animal.prototype); WalkingAnimal.prototype.walk = function() { console.log(this.getName() + ' is walking'); } Object.create sets hidden __proto__ reference to Animal.prototype but without calling constructor *Introduced in JavaScript 1.6
  • 64.
    inherits function tohide ugly stuff Function.prototype.inherits = function(parent, methods) { this.prototype = Object.create(parent.prototype); We store parent in this.prototype.$parent = parent; $parent variable. Can be useful later for(name in methods) { this.prototype[name] = methods[name]; } } We copy every method from methods object to function prototype
  • 65.
    inherits method usage varWalkingAnimal = function(name) { this.$parent.call(this, name); } WalkingAnimal.inherits(Animal, { walk: function() { console.log(this.getName() + 'is walking'); } }
  • 66.
    Or maybe don'tdo it classical ● ● ● ● ● Don't use new Don't use prototype Forgot about inheritance tree Use composition and mixins Use power of functions (including functional programming) ● Treat objects like function namespace or data container not state container ● Occasionally use Object.create and Object. defineProperty if you need
  • 67.
    References ● Douglas Crockford "JavaScript:The good parts" ● Douglas Crockford's site (http://www.crockford.com/) ● Dymitry Soshnikov's blog (http://dmitrysoshnikov.com) ● Mozilla's "A re-introduction to JavaScript" (https://developer.mozilla.org/enUS/docs/JavaScript/A_re-introduction_to_JavaScript?redirect=no) ● Angus Croll's blog (http://javascriptweblog.wordpress.com)
  • 68.
  • 69.
    Want more? Here youare director's cut ;)
  • 71.
    JavaScript primitives withmethods? var a = 1; console.log(typeof a); //returns 'number' console.log(a instanceof Number); //returns false console.log(a.toExponential()); //returns 1e+0 var b = "abc"; console.log(typeof b); //returns 'string' console.log(b instanceof String); //returns false console.log(b.slice(1)); //returns 'bc' var c = true; console.log(typeof c); //returns 'boolean' console.log(c instanceof Boolean); //returns false console.log(c.toString()); //returns 'true'
  • 72.
    The secret lifeof primitives var a = 1; a.toExponential(); It is not really method of primitive. = var a = 1; (new Number(a)).toExponential(); Every time you trying access primitive method, new object, containing primitive value is created secretly.