SlideShare a Scribd company logo
1 of 36
Download to read offline
The Mighty JS Function
Timothee Groleau - 2010-11-04
Who I am
●Timothee (Tim) Groleau
●EcmaScript coder for 10+ years (AS1, AS2, JS)
●Currently working at mig33 ( http://mig33.com )
Disclaimer / warnings
●I hope you like black and white
●Spaghetti presentation
●Examples purposely simplistic/stupid to illustrate features
●I have not looked at a real JS VM implementation
●we'll start reaaaaallly simple, then move on to interesting stuff
●coding style not consistent (I had to save spaces in these slides)
●I didn't follow Sebastiaan's advice of splitting content,
(and then I totally regretted it, but it was too late :( )
function factorial (n)
{
var fact = 1;
while (n > 1) fact *= n--;
return fact;
}
x = 5;
res = factorial(x);
alert(x); // 5
alert(res); // 120
// alert(n); // error n is not defined
// alert(fact); // error fact is not defined
What do we have here?
●Function declaration
●Function invocation
●Function arguments and parameters passing (pass by value)
●Local parameters
●Memory reclamation / garbage collection
function average ()
{
if (arguments.length <= 0) return 0;
var total = 0;
for (var i=0; i<arguments.length; i++)
{
total += arguments[i];
}
return total / arguments.length;
}
a = average(3, 5, 7, 9, 11, 8, 2);
alert(a); // 6.428571428571429
What do we have here?
●undeclared arguments
●variable length argument list
●arguments array (!!beware!! FAKE array)
var foo = {x:5}, bar = {x:6};
function whatsMyX()
{
return this.x;
}
foo.getX = whatsMyX;
bar.getX = whatsMyX;
alert( foo.getX() ); // 5
alert( bar.getX() ); // 6
alert( foo.getX === bar.getX ); // true
What do we have here?
●function references can be assigned, just like any variable
●function call operator (), can be used on any valid function reference
●'this' in a function body is dynamically resolved, and resolves to the
object the function is called from
DOMAIN = 'http://www.mig33.com';
function getURL(path)
{
return DOMAIN + path;
}
url = getURL('/about-us/jobs');
alert(url);
What do we have here?
●global variable access inside a function
●scope chain traversal
function getModuloFunc(mod)
{
return function(n)
{
return n % mod;
}
}
mod2 = getModuloFunc(2);
mod3 = getModuloFunc(3);
alert( [mod2(1), mod2(2), mod2(3), mod2(4), mod2(5)] );
alert( [mod3(1), mod3(2), mod3(3), mod3(4), mod3(5)] );
What do we have here?
●a function is being returned from another function
●the inner function is persisted
●when the inner function runs, it has access to the local variables of
the outer function
===> closures!
var x = 5;
function setup(obj) {
var x;
obj.setIt = function(a, b) {
x = a;
y = b;
}
obj.getIt = function() {
return [x, y];
}
}
o = {}; setup(o);
o.setIt(6, 7);
alert(o.getIt()); // [6, 7]
alert( [x, y] ); // [5, 7]
What do we have here?
●2 inner functions are persisted in a global object
●they both have access to the same outer function's scope
●assignment without explicit scope is done to first scope that declares
variable, or to global scope (e.g. 'y' ends up in the global scope)
Concept slide 1 – function declaration
function foo() {}
●named function
●can be forward referenced
foo = function() {}
●anonymous function
●assigned to variable foo
●makes it obvious that the function can be treated like any variable
In both cases, foo is now a reference to a function object, aka a function
reference
Concept slide 2 – functions are first class objects
They can be assigned/accessed like any other variable
function foo(){};
var bar = foo; bar();
var o = {}; o.bla = foo; o.bla();
As a consequence, they can be passed as function parameters, and be
return values from functions
function foo() { alert('hello'); };
function bar1(func) { func(); }
bar1(foo);
function bar2() { return foo; };
bar2()();
Functions can hold data
function foo(){}
bar = foo;
bar.aProperty = 'hello';
alert(foo.aProperty);
Functions are instances of the Function class (more on that later... maybe)
Concept slide 3 – function call operator: ()
The function call operator can be used on anything that evaluate to a
function reference.
var foo = function() {alert('hello');};
foo();
var bar = foo; bar();
var o = {method:foo}; o.method();
var name = 'method'; o[name]();
(function() {alert('hello');})()
var bar2 = function(){ return foo; };
bar2()();
Concept slide 4 – Scopes in javascript
No block scope in JS:
var x = 5;
{
var x = 6;
}
alert(x); // ?
Functions provide scopes
var x = 5;
function foo()
{
var x;
x = 6;
alert(x);
}
foo(); // 6
alert(x); // 5
Concept slide 5 – Scope chain / Lexical scoping
Javascript is lexically scoped (aka: just read it, it makes sense)
var x = 5;
function foo() { alert(x); }
function bar() { var x=6; foo(); }
bar(); // ?
In other words, the scope chain of a function is determined at function
creation, NOT at function invocation
The scope chain is the sequence of objects inspected for variable
resolution. Think of it as a linked list.
Concept slide 6 – Closures / Scope chain / Memory considerations I
function foo()
{
var someLargeString = 'bla';
var someOtherLargeString = 'bli';
var theNumberIneed = 5;
return function(n) {
return n + theNumberIneed;
}
}
bar = foo();
alert( bar(5) ); // 10
What happened to someLargeString and someOtherLargeString?
They are in memory for as long as a reference to the inner function exists,
but they can never be reached.
Concept slide 7 – Closures / Scope chain / Memory considerations II
Want proof?
function foo()
{
var someLargeString = 'bla';
var someOtherLargeString = 'bli';
var theNumberIneed = 5;
return function(name) {
return eval(name);
}
}
getFromScope = foo();
alert( getFromScope('someLargeString') ); // bla
alert( getFromScope('someOtherLargeString') ); // bli
alert( getFromScope('theNumberIneed') ); // 5
Concept slide 8 – Closures / Scope chain / Memory considerations III
var global_var = 2;
function f(arg)
{
var local_var_f = arg;
alert([local_var_f, global_var]);
return function(arg)
{
alert([
arg,
local_var_f,
global_var
]);
}
}
g1 = f(3); //3,2
g1(4); //4,3,2
g1(5); //5,3,2
g2 = f(6); //6,2
g2(7); //7,6,2
g2(8); //8,6,2
Concept slide 9 – Closures / Scope chain / Memory considerations IV
Let's take a look at what's really happening (boo-ring... sorry)
1) At function creation time, a 'hidden' reference is stored in the function to
point to the CURRENT scope object, this basically becomes the start of the
scope chain.
2) At function invocation
a) a new object is created to become the current scope
b) all local variables, function parameters, and arguments array are stored
in that object (i.e. 'var' is a keyword to add new members to the scope
object)
c) the new object gets the hidden link to point to the function's scope chain
d) when end of the function is reached, the scope object gets destroyed,
all local variables it carries are removed (yeah, garbage collection!)
3) IF an inner function is persisted (returned or assigned to a global object),
then the 'hidden link' to the current scope is also persisted, and since ref
count is not zero, the scope object (and ALL its local variables) are NOT
garbage collected
Concept slide 10 – to closure or not to closure? I
function setup(obj)
{
var someVar = 'bla';
obj.count = 0;
obj.aMethod = function()
{
this.count++;
}
}
o1 = {}; setup(o1);
o2 = {}; setup(o2);
Good or bad?
alert( o1.aMethod === o2.aMethod ); // false
Concept slide 11 – to closure or not to closure? II
function _method()
{
this.count++;
}
function setup(obj)
{
var someVar = 'bla';
obj.count = 0;
obj.aMethod = _method;
}
o1 = {}; setup(o1);
o2 = {}; setup(o2);
alert( o1.aMethod === o2.aMethod ); // true
Putting it all together – private scopes
(function(){
var DOMAIN = 'http://www.mig33.com';
getURL = function(path)
{
return DOMAIN + path;
}
})();
url = getURL('/about-us/jobs');
alert(url);
Putting it all together – Classes with private statics
(function(){
// private static
var prefix = 'M33_WIDGET_';
var count = 0;
var domain = 'http://www.mig33.com';
MyClass = function() {
this.id = prefix + (++count);
};
o = MyClass.prototype;
o.method1 = function(path) { /* … */ };
})();
m = new MyClass();
alert( m.id );
Putting it all together – Instance privates (CrockFord style)
function Foo(blarg)
{
var self = this; // Capture self-ref in closure
this.datum = blarg;
var private_data = "whatever"; // Captured in closure
this.standard_method = function() {
return this.datum;
};
function private_method() {
self.datum += 1; // Accesses member via closure
return private_data; // Accesses closure
}
this.privileged_method = function() {
private_data += "!"; // Accesses closure
return private_method();
};
}
o = new Foo(5);
o.privileged_method();
alert( o.bar() );
alert( o.private_data ); // undefined
Putting it all together – Classes with scopes, My own practice
Enclosing closure for each class definition
=> allow for private static vars and methods
Naming convention on instance private vars and methods (pragmatic, saves
memory, easier to test)
Enclosing closure for each namespace.
Whatever – Recursion and scope chain I
function factorial(n)
{
if (n < 2) return 1;
return n * factorial(n-1);
}
Math.factorial = factorial;
alert( Math.factorial(5) ); // 120
// later in code
factorial = function(n) {
return 1;
}
alert( Math.factorial(5) ); // 5
Whatever – Recursion and scope chain II
function factorial(n)
{
if (n < 2) return 1;
return n * arguments.callee(n-1);
}
Math.factorial = factorial;
alert( Math.factorial(5) ); // 120
// later in code
factorial = function(n) {
return 1;
}
alert( Math.factorial(5) ); // 120
Whatever – Arguments.callee for function static variables
function click()
{
if (--arguments.callee.tries < 0)
{
alert('forbidden'); return false;
}
alert('click'); return true;
}
click.tries = 3;
click(); // click
click(); // click
click(); // click
click(); // forbidden
Function class – Function.apply / Function.call I
Function.apply and function.call are used to manually set the meaning of
'this'
function getX(y, z)
{
alert( [this.x, y, z] );
}
o1 = {x:5};
o2 = {x:6};
getX.apply(o1, [6, 7]);
getX.apply(o2, [7, 8]);
getX.call(o1, 6, 7);
getX.call(o2, 7, 8);
Function class – Function.apply / Function.call II
variable length arguments are typically not known in advance, use
function.apply to pass an array that will translate to arguments
function average ()
{
if (arguments.length <= 0) return 0;
var total = 0;
for (var i=0; i<arguments.length; i++)
{
total += arguments[i];
}
return total / arguments.length;
}
data = [3, 5, 7, 9, 11, 8, 2];
a = average.apply(null, data);
alert(a); // 6.428571428571429
Delegation I
function MyClass(name){
this.name = name;
this.setup();
}
MyClass.prototype.setup = function() {
var b = document.getElementsByTagName('body')[0];
b.onclick = this.sayMyName;
}
MyClass.prototype.sayMyName = function() {
alert( this.name );
}
m = new MyClass('tim');
// click in browser => undefined!
Delegation II – Store a reference to 'this' in the closure
function MyClass(name) {
this.name = name;
this.setup();
}
MyClass.prototype.setup = function() {
var b = document.getElementsByTagName('body')[0];
var self = this;
b.onclick = function(){
self.sayMyName();
}
}
MyClass.prototype.sayMyName = function(){
alert( this.name );
}
m = new MyClass('tim');
// click in browser => tim!
Delegation III – use a helper function with function reference
delegate = function(obj, func)
{
return function()
{
return func.apply(obj, arguments);
}
}
o1 = {
name: 'o1',
sayMyName: function(a){
alert(a + ' ' + this.name)
}
};
o2 = {name: 'o2'};
o2.sayIt = delegate(o1, o1.sayMyName);
o2.sayIt('hello');
Delegation IV – use a helper function with a function name
delegate = function(obj, funcName)
{
return function()
{
return obj[funcName].apply(obj, arguments);
}
}
o1 = {
name: 'o1',
sayMyName: function(a){
alert(a + ' ' + this.name)
}
};
o2 = {name: 'o2'};
o2.sayIt = delegate(o1, 'sayMyName');
o2.sayIt('hello'); // 'hello o1'
Delegation V – allow setting fixed parameters, when delegating
delegate = function(obj, funcName, greeting)
{
return function()
{
return obj[funcName].apply(obj, [greeting]);
}
}
o1 = {
name: 'o1',
sayMyName: function(a){
alert(a + ' ' + this.name)
}
};
o2 = {name: 'o2'};
o2.sayIt = delegate(o1, 'sayMyName', 'bonjour');
o2.sayIt('hello'); // 'bonjour o1'
Trivia I
In a browser, the global scope is the window object itself :)
a = 5;
alert( window.a ); // 5
Trivia II - Assignment without explicit scope
Assignment without explicit scope is done to the first scope object that had
the variable declared locally, or global scope if none:
var x = 5;
function foo()
{
x = 6;
}
foo(); alert(x); // 6
/*======================================*/
var x = 5;
function foo()
{
var x;
return function()
{
x = 6;
}
}
foo()(); alert(x); // 5
Conclusion
Functions in JS are VERY powerful
Closures are probably the most useful feature of JS
Beware, you can get bitten hard, especially with long closures (e.g. jQuery
has one fat outer function scope of 6,500+ lines). Watch out for:
●local variables in outer scopes that are left alive forever
●function duplication where they are not required
Especially true in the days of cool ajaxy libraries like jQuery or ExtJS, which
make it very easy to use closures without completely understanding them.
I'm not bashing jQuery, I looove jQuery, just know your tools well! :D

More Related Content

What's hot

Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcescorehard_by
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеSergey Platonov
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Sergey Platonov
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerAndrey Karpov
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxyginecorehard_by
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
модели акторов в с++ миф или реальность
модели акторов в с++ миф или реальностьмодели акторов в с++ миф или реальность
модели акторов в с++ миф или реальностьcorehard_by
 
Modern C++ Concurrency API
Modern C++ Concurrency APIModern C++ Concurrency API
Modern C++ Concurrency APISeok-joon Yun
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Sergey Platonov
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereSergey Platonov
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015NAVER / MusicPlatform
 
Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Sergey Platonov
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9Andrey Zakharevich
 
4. Обработка ошибок, исключения, отладка
4. Обработка ошибок, исключения, отладка4. Обработка ошибок, исключения, отладка
4. Обработка ошибок, исключения, отладкаDEVTYPE
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортSergey Platonov
 

What's hot (20)

Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
модели акторов в с++ миф или реальность
модели акторов в с++ миф или реальностьмодели акторов в с++ миф или реальность
модели акторов в с++ миф или реальность
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
 
Modern C++ Concurrency API
Modern C++ Concurrency APIModern C++ Concurrency API
Modern C++ Concurrency API
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
C++ aptitude
C++ aptitudeC++ aptitude
C++ aptitude
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
Message in a bottle
Message in a bottleMessage in a bottle
Message in a bottle
 
Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9
 
4. Обработка ошибок, исключения, отладка
4. Обработка ошибок, исключения, отладка4. Обработка ошибок, исключения, отладка
4. Обработка ошибок, исключения, отладка
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
C++ L05-Functions
C++ L05-FunctionsC++ L05-Functions
C++ L05-Functions
 

Viewers also liked

P grey kotlerdeliveringvalue
P grey kotlerdeliveringvalueP grey kotlerdeliveringvalue
P grey kotlerdeliveringvaluepsgrey
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side JavascriptJulie Iskander
 
Code for kombol - Objects and Functions in JS and NodeJS
Code for kombol - Objects and Functions in JS and NodeJSCode for kombol - Objects and Functions in JS and NodeJS
Code for kombol - Objects and Functions in JS and NodeJSRiyadh Al Nur
 
2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShareSlideShare
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShareSlideShare
 

Viewers also liked (7)

P grey kotlerdeliveringvalue
P grey kotlerdeliveringvalueP grey kotlerdeliveringvalue
P grey kotlerdeliveringvalue
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
Code for kombol - Objects and Functions in JS and NodeJS
Code for kombol - Objects and Functions in JS and NodeJSCode for kombol - Objects and Functions in JS and NodeJS
Code for kombol - Objects and Functions in JS and NodeJS
 
Javascript: master this
Javascript: master thisJavascript: master this
Javascript: master this
 
Js ppt
Js pptJs ppt
Js ppt
 
2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShare
 

Similar to The mighty js_function

Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScriptNascenia IT
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.Jin-Hwa Kim
 
LISA QooxdooTutorial Slides
LISA QooxdooTutorial SlidesLISA QooxdooTutorial Slides
LISA QooxdooTutorial SlidesTobias Oetiker
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptMichael Girouard
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The LandingHaci Murat Yaman
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript FunctionsBrian Moschel
 
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
 
ESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowKrzysztof Szafranek
 

Similar to The mighty js_function (20)

Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
 
LISA QooxdooTutorial Slides
LISA QooxdooTutorial SlidesLISA QooxdooTutorial Slides
LISA QooxdooTutorial Slides
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Es6 hackathon
Es6 hackathonEs6 hackathon
Es6 hackathon
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
Advanced JavaScript
Advanced JavaScript Advanced JavaScript
Advanced JavaScript
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
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)
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
 
ESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. Now
 
"let ECMAScript = 6"
"let ECMAScript = 6" "let ECMAScript = 6"
"let ECMAScript = 6"
 

Recently uploaded

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 

Recently uploaded (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 

The mighty js_function

  • 1. The Mighty JS Function Timothee Groleau - 2010-11-04
  • 2. Who I am ●Timothee (Tim) Groleau ●EcmaScript coder for 10+ years (AS1, AS2, JS) ●Currently working at mig33 ( http://mig33.com ) Disclaimer / warnings ●I hope you like black and white ●Spaghetti presentation ●Examples purposely simplistic/stupid to illustrate features ●I have not looked at a real JS VM implementation ●we'll start reaaaaallly simple, then move on to interesting stuff ●coding style not consistent (I had to save spaces in these slides) ●I didn't follow Sebastiaan's advice of splitting content, (and then I totally regretted it, but it was too late :( )
  • 3. function factorial (n) { var fact = 1; while (n > 1) fact *= n--; return fact; } x = 5; res = factorial(x); alert(x); // 5 alert(res); // 120 // alert(n); // error n is not defined // alert(fact); // error fact is not defined What do we have here? ●Function declaration ●Function invocation ●Function arguments and parameters passing (pass by value) ●Local parameters ●Memory reclamation / garbage collection
  • 4. function average () { if (arguments.length <= 0) return 0; var total = 0; for (var i=0; i<arguments.length; i++) { total += arguments[i]; } return total / arguments.length; } a = average(3, 5, 7, 9, 11, 8, 2); alert(a); // 6.428571428571429 What do we have here? ●undeclared arguments ●variable length argument list ●arguments array (!!beware!! FAKE array)
  • 5. var foo = {x:5}, bar = {x:6}; function whatsMyX() { return this.x; } foo.getX = whatsMyX; bar.getX = whatsMyX; alert( foo.getX() ); // 5 alert( bar.getX() ); // 6 alert( foo.getX === bar.getX ); // true What do we have here? ●function references can be assigned, just like any variable ●function call operator (), can be used on any valid function reference ●'this' in a function body is dynamically resolved, and resolves to the object the function is called from
  • 6. DOMAIN = 'http://www.mig33.com'; function getURL(path) { return DOMAIN + path; } url = getURL('/about-us/jobs'); alert(url); What do we have here? ●global variable access inside a function ●scope chain traversal
  • 7. function getModuloFunc(mod) { return function(n) { return n % mod; } } mod2 = getModuloFunc(2); mod3 = getModuloFunc(3); alert( [mod2(1), mod2(2), mod2(3), mod2(4), mod2(5)] ); alert( [mod3(1), mod3(2), mod3(3), mod3(4), mod3(5)] ); What do we have here? ●a function is being returned from another function ●the inner function is persisted ●when the inner function runs, it has access to the local variables of the outer function ===> closures!
  • 8. var x = 5; function setup(obj) { var x; obj.setIt = function(a, b) { x = a; y = b; } obj.getIt = function() { return [x, y]; } } o = {}; setup(o); o.setIt(6, 7); alert(o.getIt()); // [6, 7] alert( [x, y] ); // [5, 7] What do we have here? ●2 inner functions are persisted in a global object ●they both have access to the same outer function's scope ●assignment without explicit scope is done to first scope that declares variable, or to global scope (e.g. 'y' ends up in the global scope)
  • 9. Concept slide 1 – function declaration function foo() {} ●named function ●can be forward referenced foo = function() {} ●anonymous function ●assigned to variable foo ●makes it obvious that the function can be treated like any variable In both cases, foo is now a reference to a function object, aka a function reference
  • 10. Concept slide 2 – functions are first class objects They can be assigned/accessed like any other variable function foo(){}; var bar = foo; bar(); var o = {}; o.bla = foo; o.bla(); As a consequence, they can be passed as function parameters, and be return values from functions function foo() { alert('hello'); }; function bar1(func) { func(); } bar1(foo); function bar2() { return foo; }; bar2()(); Functions can hold data function foo(){} bar = foo; bar.aProperty = 'hello'; alert(foo.aProperty); Functions are instances of the Function class (more on that later... maybe)
  • 11. Concept slide 3 – function call operator: () The function call operator can be used on anything that evaluate to a function reference. var foo = function() {alert('hello');}; foo(); var bar = foo; bar(); var o = {method:foo}; o.method(); var name = 'method'; o[name](); (function() {alert('hello');})() var bar2 = function(){ return foo; }; bar2()();
  • 12. Concept slide 4 – Scopes in javascript No block scope in JS: var x = 5; { var x = 6; } alert(x); // ? Functions provide scopes var x = 5; function foo() { var x; x = 6; alert(x); } foo(); // 6 alert(x); // 5
  • 13. Concept slide 5 – Scope chain / Lexical scoping Javascript is lexically scoped (aka: just read it, it makes sense) var x = 5; function foo() { alert(x); } function bar() { var x=6; foo(); } bar(); // ? In other words, the scope chain of a function is determined at function creation, NOT at function invocation The scope chain is the sequence of objects inspected for variable resolution. Think of it as a linked list.
  • 14. Concept slide 6 – Closures / Scope chain / Memory considerations I function foo() { var someLargeString = 'bla'; var someOtherLargeString = 'bli'; var theNumberIneed = 5; return function(n) { return n + theNumberIneed; } } bar = foo(); alert( bar(5) ); // 10 What happened to someLargeString and someOtherLargeString? They are in memory for as long as a reference to the inner function exists, but they can never be reached.
  • 15. Concept slide 7 – Closures / Scope chain / Memory considerations II Want proof? function foo() { var someLargeString = 'bla'; var someOtherLargeString = 'bli'; var theNumberIneed = 5; return function(name) { return eval(name); } } getFromScope = foo(); alert( getFromScope('someLargeString') ); // bla alert( getFromScope('someOtherLargeString') ); // bli alert( getFromScope('theNumberIneed') ); // 5
  • 16. Concept slide 8 – Closures / Scope chain / Memory considerations III var global_var = 2; function f(arg) { var local_var_f = arg; alert([local_var_f, global_var]); return function(arg) { alert([ arg, local_var_f, global_var ]); } } g1 = f(3); //3,2 g1(4); //4,3,2 g1(5); //5,3,2 g2 = f(6); //6,2 g2(7); //7,6,2 g2(8); //8,6,2
  • 17. Concept slide 9 – Closures / Scope chain / Memory considerations IV Let's take a look at what's really happening (boo-ring... sorry) 1) At function creation time, a 'hidden' reference is stored in the function to point to the CURRENT scope object, this basically becomes the start of the scope chain. 2) At function invocation a) a new object is created to become the current scope b) all local variables, function parameters, and arguments array are stored in that object (i.e. 'var' is a keyword to add new members to the scope object) c) the new object gets the hidden link to point to the function's scope chain d) when end of the function is reached, the scope object gets destroyed, all local variables it carries are removed (yeah, garbage collection!) 3) IF an inner function is persisted (returned or assigned to a global object), then the 'hidden link' to the current scope is also persisted, and since ref count is not zero, the scope object (and ALL its local variables) are NOT garbage collected
  • 18. Concept slide 10 – to closure or not to closure? I function setup(obj) { var someVar = 'bla'; obj.count = 0; obj.aMethod = function() { this.count++; } } o1 = {}; setup(o1); o2 = {}; setup(o2); Good or bad? alert( o1.aMethod === o2.aMethod ); // false
  • 19. Concept slide 11 – to closure or not to closure? II function _method() { this.count++; } function setup(obj) { var someVar = 'bla'; obj.count = 0; obj.aMethod = _method; } o1 = {}; setup(o1); o2 = {}; setup(o2); alert( o1.aMethod === o2.aMethod ); // true
  • 20. Putting it all together – private scopes (function(){ var DOMAIN = 'http://www.mig33.com'; getURL = function(path) { return DOMAIN + path; } })(); url = getURL('/about-us/jobs'); alert(url);
  • 21. Putting it all together – Classes with private statics (function(){ // private static var prefix = 'M33_WIDGET_'; var count = 0; var domain = 'http://www.mig33.com'; MyClass = function() { this.id = prefix + (++count); }; o = MyClass.prototype; o.method1 = function(path) { /* … */ }; })(); m = new MyClass(); alert( m.id );
  • 22. Putting it all together – Instance privates (CrockFord style) function Foo(blarg) { var self = this; // Capture self-ref in closure this.datum = blarg; var private_data = "whatever"; // Captured in closure this.standard_method = function() { return this.datum; }; function private_method() { self.datum += 1; // Accesses member via closure return private_data; // Accesses closure } this.privileged_method = function() { private_data += "!"; // Accesses closure return private_method(); }; } o = new Foo(5); o.privileged_method(); alert( o.bar() ); alert( o.private_data ); // undefined
  • 23. Putting it all together – Classes with scopes, My own practice Enclosing closure for each class definition => allow for private static vars and methods Naming convention on instance private vars and methods (pragmatic, saves memory, easier to test) Enclosing closure for each namespace.
  • 24. Whatever – Recursion and scope chain I function factorial(n) { if (n < 2) return 1; return n * factorial(n-1); } Math.factorial = factorial; alert( Math.factorial(5) ); // 120 // later in code factorial = function(n) { return 1; } alert( Math.factorial(5) ); // 5
  • 25. Whatever – Recursion and scope chain II function factorial(n) { if (n < 2) return 1; return n * arguments.callee(n-1); } Math.factorial = factorial; alert( Math.factorial(5) ); // 120 // later in code factorial = function(n) { return 1; } alert( Math.factorial(5) ); // 120
  • 26. Whatever – Arguments.callee for function static variables function click() { if (--arguments.callee.tries < 0) { alert('forbidden'); return false; } alert('click'); return true; } click.tries = 3; click(); // click click(); // click click(); // click click(); // forbidden
  • 27. Function class – Function.apply / Function.call I Function.apply and function.call are used to manually set the meaning of 'this' function getX(y, z) { alert( [this.x, y, z] ); } o1 = {x:5}; o2 = {x:6}; getX.apply(o1, [6, 7]); getX.apply(o2, [7, 8]); getX.call(o1, 6, 7); getX.call(o2, 7, 8);
  • 28. Function class – Function.apply / Function.call II variable length arguments are typically not known in advance, use function.apply to pass an array that will translate to arguments function average () { if (arguments.length <= 0) return 0; var total = 0; for (var i=0; i<arguments.length; i++) { total += arguments[i]; } return total / arguments.length; } data = [3, 5, 7, 9, 11, 8, 2]; a = average.apply(null, data); alert(a); // 6.428571428571429
  • 29. Delegation I function MyClass(name){ this.name = name; this.setup(); } MyClass.prototype.setup = function() { var b = document.getElementsByTagName('body')[0]; b.onclick = this.sayMyName; } MyClass.prototype.sayMyName = function() { alert( this.name ); } m = new MyClass('tim'); // click in browser => undefined!
  • 30. Delegation II – Store a reference to 'this' in the closure function MyClass(name) { this.name = name; this.setup(); } MyClass.prototype.setup = function() { var b = document.getElementsByTagName('body')[0]; var self = this; b.onclick = function(){ self.sayMyName(); } } MyClass.prototype.sayMyName = function(){ alert( this.name ); } m = new MyClass('tim'); // click in browser => tim!
  • 31. Delegation III – use a helper function with function reference delegate = function(obj, func) { return function() { return func.apply(obj, arguments); } } o1 = { name: 'o1', sayMyName: function(a){ alert(a + ' ' + this.name) } }; o2 = {name: 'o2'}; o2.sayIt = delegate(o1, o1.sayMyName); o2.sayIt('hello');
  • 32. Delegation IV – use a helper function with a function name delegate = function(obj, funcName) { return function() { return obj[funcName].apply(obj, arguments); } } o1 = { name: 'o1', sayMyName: function(a){ alert(a + ' ' + this.name) } }; o2 = {name: 'o2'}; o2.sayIt = delegate(o1, 'sayMyName'); o2.sayIt('hello'); // 'hello o1'
  • 33. Delegation V – allow setting fixed parameters, when delegating delegate = function(obj, funcName, greeting) { return function() { return obj[funcName].apply(obj, [greeting]); } } o1 = { name: 'o1', sayMyName: function(a){ alert(a + ' ' + this.name) } }; o2 = {name: 'o2'}; o2.sayIt = delegate(o1, 'sayMyName', 'bonjour'); o2.sayIt('hello'); // 'bonjour o1'
  • 34. Trivia I In a browser, the global scope is the window object itself :) a = 5; alert( window.a ); // 5
  • 35. Trivia II - Assignment without explicit scope Assignment without explicit scope is done to the first scope object that had the variable declared locally, or global scope if none: var x = 5; function foo() { x = 6; } foo(); alert(x); // 6 /*======================================*/ var x = 5; function foo() { var x; return function() { x = 6; } } foo()(); alert(x); // 5
  • 36. Conclusion Functions in JS are VERY powerful Closures are probably the most useful feature of JS Beware, you can get bitten hard, especially with long closures (e.g. jQuery has one fat outer function scope of 6,500+ lines). Watch out for: ●local variables in outer scopes that are left alive forever ●function duplication where they are not required Especially true in the days of cool ajaxy libraries like jQuery or ExtJS, which make it very easy to use closures without completely understanding them. I'm not bashing jQuery, I looove jQuery, just know your tools well! :D