Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Exciting JavaScript
 What makes it unique, how to use it.

           Eugene Lazutkin
  Dallas, TX, ClubAjax on 2/2/2010

...
Disclaimer

• I will use JavaScript, JS, and ECMAScript
  interchangeably.
• The material is mostly based on
  ECMAScript ...
Why JavaScript?
• Browsers.
• CommonJS (ex-ServerJS) is gaining steam.
• CouchDB uses it to define “views”.
• Node.js with ...
JS the Language I
• JavaScript packages a formidable set of
  tools we can leverage to reduce
  complexity.
• While it doe...
JS the Language II
• Following paradigms can be supported:
 • Object-oriented programming (OOP).
 • Functional programming...
JS the Language III
• Let’s do an inventory of the language
  facilities:
  • To understand how JavaScript is different
  ...
Inventory
 Available tools.




        7
1 st   class functions

• We can create them on the fly.
 • Anonymous function.
• We can write them inline.
 • Function lit...
Function examples I
// “normal” function
function double1(x){
    return 2 * x;
}
// anonymous function
var double2 = func...
Function examples II
// takes function as an argument
function scale(f, x){
    return f(x);
}
// returns a function funct...
Closures I
• Closures are:
 • The most mysterious part of JavaScript.
 • The bane of beginners, and the source of
    most...
Closures II
• It is a function, which uses variables from its
  lexical environment.
• JavaScript closure uses external va...
Closures: examples
var a = 1;
// available here: a
function f1(x){
    var b = 2;
    // available here: a, f1, b, x
    f...
var: fine points I
• Only functions produce lexical scopes.
• It doesn’t matter where var statement is
  encountered: a var...
var: fine points II
function f(x){
    var n = 5, acc = 0;
    // available here: f, x, n, acc, i, d, b
    for(var i = 0; ...
Closures vs. Pure
• Pure functions:
 • Stateless.
 • Have no side effects.
 • Operate only on their arguments.
• Always re...
Why pure?
• Theoretically:
 • Easier to analyze the program for
    correctness.
 • Code can be rearranged and optimized
 ...
Practical closures I
// generate unique DOM ID
var uniqId = (function(){
 // truly private variables
 var prefix = “uniq_”...
Practical closures II
// parameterize a function
var scale = function(factor){
 return function(x){
     return factor * x...
this: fine points I
• Every function is called in a context of an
  object or the global scope.

• this is a pseudo-variabl...
this: fine points II
• Specifying a context implicitly:
  var name = “global”;
  var abc = function(a, b, c){ alert(this.na...
this: fine points III
• Specifying a context explicitly:
  var abc = function(a, b, c){ alert(this.name); };
  var myObj = ...
this: fine points IV
• Accessing outer this – just reassign this
  to a regular variable:
  function f1(){
   // this is “t...
arguments
• Another pseudo-variable with fine points
  and restrictions similar to this.
• It has two cool properties:
 • “...
Hash-based objects I
• Everything is an object. Sounds familiar?
• All objects are hash-based dictionaries of
  key-value ...
Hash-based objects II
• We can add/remove custom properties at
  will.
 • Read-only objects: numbers, strings,
    boolean...
OOP
Different flavors and approaches.




               27
OOP: short intro
• Object-oriented programming is an
  important paradigm.
• It is a way to organize/partition code into
 ...
OOP: duck-typing I
• We can do OOP without classes!
• Example:
 • We have an iterator interface:
   • next() – returns “ne...
OOP: duck-typing II
• Notable:
 • The iterator interface here is a concept,
    it does’t have any corresponding code.
  •...
OOP: duck-typing III
• Let’s implement a counter from 1 to 5:
  var it = {
      value: 1, limit: 5,
      hasNext: functi...
OOP: duck-typing IV
• Let’s implement a stack-based iterator:
  var it = {
      stack: [1, 2, 3, 4, 5],
      hasNext: fu...
No constructors?
• What if we want to create several similar
  objects?
• We need constructors.
• Yes, it is possible to h...
OOP: factories I
• Any function that return an object will do.
• Let’s construct our simple iterator:
  function makeIt(fr...
OOP: factories II
• Closure version of our simple iterator:
  function makeIt(from, to){
      var counter = from;
      f...
OOP: prototypes
• JavaScript has notions of constructors and
  inheritance.
• But it doesn’t provide classes per se.
• The...
OOP: constructor I
• Constructor can be any function.
• When it runs its context is set to a newly
  created object.
  • U...
OOP: constructor II
• Constructor has one important property:
  prototype.
  • It points to a delegatee object.
• Usually ...
OOP: new operator
• new creates a proper object (a generic
  object for user-defined constructors).

• It takes a prototype...
OOP: delegate
• Now we can write a generic delegate:
  var delegate = (function(){
   function temp(){} // it’ll hold a pr...
OOP: using delegate I
var a = {
 hello: function(){ console.log(“Hello!”); },
 zen: function(){ console.log(“O-O-OM”); }
}...
OOP: using delegate II
 var c = delegate(b);
 a.hello(); // Hello!
 b.hello(); // Huh?
 c.hello(); // Huh?
 c.hello = func...
OOP: advanced I
• We just saw how we can organize our code
  using the single inheritance.
• Many JS libraries provide OOP...
OOP: advanced II
• dojo.declare() provides:
 • Multiple inheritance based on class
    linearization (using C3 MRO).
 • Ch...
OOP: advanced III


• This is a big topic, which we can discuss
  some other time.




                      45
AOP
Important aspects.




        46
AOP: short intro I
• Aspect-oriented programming pays
  attention to cross-cutting concerns
  implemented as advices, whic...
AOP: short intro II
• Examples of cross-cutting concerns:
 • Time/profile a function call.
 • Put all newly constructed obj...
AOP: short intro III
• All examples demonstrate common things:
 • Code required to perform an advice
    does not depend o...
AOP in JavaScript
• We can reliably intercept one thing: a
  method call.
  • In most cases it is more than enough for
   ...
AOP: toy example I
• Let’s implement the “afterReturning”
  advice:
  function attachAfterReturning(obj, name, advice){
  ...
AOP: toy example II
• Let’s implement the “before” advice:
  function attachBefore(obj, name, advice){
      var old = obj...
AOP: toy example III
• Let’s implement the “around” advice:
  function attachAround(obj, name, advice){
      var old = ob...
AOP: advice example I
•   Simple tracer as “around” advice:
    var tracer = (function(){
     var stack = [];
     return...
AOP: using tracer
var fact = {
 fact: function(n){ return n < 2 ? 1 : n * this.fact(n); }
};
attachAround(fact, “fact”, tr...
AOP: advice example II
• Simple 1-arg memoization as two advices:
  var memoizer = function(){
   var cache = {};
   var m...
AOP: using memoizer
var fact = {
 fact: function(n){ return n < 2 ? 1 : n * this.fact(n); }
};
var mem = memoizer();
attac...
AOP and OOP I
• There are some parallels between AOP and
  OOP:
 • Method chaining can be imagined as
    advices:
   • Co...
AOP and OOP II
• Super calls (inherited() calls) can be
  represented as “around” advice.
• These similarities are not by ...
More on AOP

• I wrote a blog post about AOP in JS and
  how it is implemented in Dojo:
 • http://lazutkin.com/blog/2008/m...
Intermediate stop
• …and I ran out of time.
• Next month we will talk about:
 • Functional programming (FP).
 • Domain-spe...
About me
• I am an independent software developer.
• My web site:
 • http://lazutkin.com
• Follow me on Tweeter:
 • http:/...
Nächste SlideShare
Wird geladen in …5
×

Exciting JavaScript - Part I

8.369 Aufrufe

Veröffentlicht am

JavaScript and popular programming paradigms (OOP, AOP, FP, DSL). Overview of the language to see what tools we can leverage to reduce complexity of our projects.

This part goes over language features and looks at OOP and AOP with JavaScript.

The presentation was delivered at ClubAJAX on 2/2/2010.
Blog post: http://lazutkin.com/blog/2010/feb/5/exciting-js-1/
Continued in Part II: http://www.slideshare.net/elazutkin/exciting-javascript-part-ii

Veröffentlicht in: Technologie

Exciting JavaScript - Part I

  1. Exciting JavaScript What makes it unique, how to use it. Eugene Lazutkin Dallas, TX, ClubAjax on 2/2/2010 1
  2. Disclaimer • I will use JavaScript, JS, and ECMAScript interchangeably. • The material is mostly based on ECMAScript 3. 2
  3. Why JavaScript? • Browsers. • CommonJS (ex-ServerJS) is gaining steam. • CouchDB uses it to define “views”. • Node.js with its asynchronous event-based I/O is red hot. • An explosion of JavaScript run-time environments and libraries. 3
  4. JS the Language I • JavaScript packages a formidable set of tools we can leverage to reduce complexity. • While it doesn’t provide a direct support for some programming paradigms, it has proper tools for us to do it. 4
  5. JS the Language II • Following paradigms can be supported: • Object-oriented programming (OOP). • Functional programming (FP). • Aspect-oriented programming (AOP). • Event-driven programming (EDP). • Much more. 5
  6. JS the Language III • Let’s do an inventory of the language facilities: • To understand how JavaScript is different from other languages. • To understand what we can use to improve meta-programming techniques. 6
  7. Inventory Available tools. 7
  8. 1 st class functions • We can create them on the fly. • Anonymous function. • We can write them inline. • Function literals. 8
  9. Function examples I // “normal” function function double1(x){ return 2 * x; } // anonymous function var double2 = function(x){ return 2 * x; }; 9
  10. Function examples II // takes function as an argument function scale(f, x){ return f(x); } // returns a function function var makeDouble = function(){ return function(x){ return 2 * x; }; }; // combine them var result = scale(makeDouble, 5); 10
  11. Closures I • Closures are: • The most mysterious part of JavaScript. • The bane of beginners, and the source of most their errors. • The cornerstone of Functional Programming in JavaScript. 11
  12. Closures II • It is a function, which uses variables from its lexical environment. • JavaScript closure uses external variables by reference. • It can consume, and modify external objects by name. 12
  13. Closures: examples var a = 1; // available here: a function f1(x){ var b = 2; // available here: a, f1, b, x function f2(y){ var c = 3; // available here: a, f1, b, x, f2, c, y return a + b + c + x + y; } } 13
  14. var: fine points I • Only functions produce lexical scopes. • It doesn’t matter where var statement is encountered: a variable is available everywhere in the function body. • Initialization is performed at the point of declaration. 14
  15. var: fine points II function f(x){ var n = 5, acc = 0; // available here: f, x, n, acc, i, d, b for(var i = 0; i < n; ++i){ var d = 2 * i; acc += d; } // b is available here yet undefined var b = 1000; return t + b * x; } 15
  16. Closures vs. Pure • Pure functions: • Stateless. • Have no side effects. • Operate only on their arguments. • Always return the same value for the same arguments. 16
  17. Why pure? • Theoretically: • Easier to analyze the program for correctness. • Code can be rearranged and optimized by compilers. • Opens up other techniques like lazy evaluations. 17
  18. Practical closures I // generate unique DOM ID var uniqId = (function(){ // truly private variables var prefix = “uniq_”, n = 0; return function(){ do{ var name = prefix + (n++); }while(document.getElementById(name)); return name; }; })(); 18
  19. Practical closures II // parameterize a function var scale = function(factor){ return function(x){ return factor * x; }; }; // use var double = scale(2), triple = scale(3); var x = double(21); var y = triple(14); 19
  20. this: fine points I • Every function is called in a context of an object or the global scope. • this is a pseudo-variable, which always points to the current context. • It cannot be pulled from a closure. • Contexts are not inherited. 20
  21. this: fine points II • Specifying a context implicitly: var name = “global”; var abc = function(a, b, c){ alert(this.name); }; var myObj = {name: “myObj”, method: abc}; // calling method in the context of myObj myObj.method(1, 2, 3); // this === myObj myObj[“method”](1, 2, 3); // this === myObj // calling function in the global context abc(1, 2, 3); // this === global 21
  22. this: fine points III • Specifying a context explicitly: var abc = function(a, b, c){ alert(this.name); }; var myObj = {name: “myObj”}; // calling method in the context of myObj abc.apply(myObj, [1, 2, 3]); // this === myObj abc.call(myObj, 1, 2, 3); // this === myObj 22
  23. this: fine points IV • Accessing outer this – just reassign this to a regular variable: function f1(){ // this is “this #1” var self = this; function f2(){ // this is “this #2” // generally “this #2” !== “this #1” // but “self” is guaranteed to be “this #1” } 23
  24. arguments • Another pseudo-variable with fine points and restrictions similar to this. • It has two cool properties: • “arguments.caller” to specify who calls you function. • “arguments.callee” to specify your function anonymously. 24
  25. Hash-based objects I • Everything is an object. Sounds familiar? • All objects are hash-based dictionaries of key-value pairs. • Hash-based the access is constant. • Embedded sub-objects and references can produce arbitrary complex graphs. 25
  26. Hash-based objects II • We can add/remove custom properties at will. • Read-only objects: numbers, strings, booleans, null, undefined. • Objects are represented by references. • Read-only objects simulate the “value” semantics. 26
  27. OOP Different flavors and approaches. 27
  28. OOP: short intro • Object-oriented programming is an important paradigm. • It is a way to organize/partition code into simple objects, which encapsulate state, and associated functionality. • There are many flavors of OOP. • The simplest ones are the most useful. 28
  29. OOP: duck-typing I • We can do OOP without classes! • Example: • We have an iterator interface: • next() – returns “next” object. • hasNext() – returns true, if there is “next” object, and false otherwise. 29
  30. OOP: duck-typing II • Notable: • The iterator interface here is a concept, it does’t have any corresponding code. • We don’t derive anything from anything. • We don’t even need a class. • We rely on human conventions rather than syntactic/semantic contracts. 30
  31. OOP: duck-typing III • Let’s implement a counter from 1 to 5: var it = { value: 1, limit: 5, hasNext: function(){ return this.value <= this.limit; }, next: function(){ return this.value++; } }; // consumer function consume(it){ while(it.hasNext()){ alert(it.next()); } } 31
  32. OOP: duck-typing IV • Let’s implement a stack-based iterator: var it = { stack: [1, 2, 3, 4, 5], hasNext: function(){ return this.stack.length; }, next: function(){ return this.stack.pop(); } }; // consumer is exactly the same function consume(it){ while(it.hasNext()){ alert(it.next()); } } 32
  33. No constructors? • What if we want to create several similar objects? • We need constructors. • Yes, it is possible to have constructors without classes. 33
  34. OOP: factories I • Any function that return an object will do. • Let’s construct our simple iterator: function makeIt(from, to){ return { value: from, limit: to, hasNext: function(){ return this.value <= this.limit; }, next: function(){ return this.value++; } }; } 34
  35. OOP: factories II • Closure version of our simple iterator: function makeIt(from, to){ var counter = from; function hasNext(){ return counter <= to; } function next(){ return counter++; } return { hasNext: hasNext, next: next }; } 35
  36. OOP: prototypes • JavaScript has notions of constructors and inheritance. • But it doesn’t provide classes per se. • The inheritance is of prototypal nature: • Objects can delegate (statically) some properties to another object, and so on. 36
  37. OOP: constructor I • Constructor can be any function. • When it runs its context is set to a newly created object. • Usually it is modified as a part of initialization. • Alternatively a constructor can return a totally different object (rarely used). 37
  38. OOP: constructor II • Constructor has one important property: prototype. • It points to a delegatee object. • Usually a constructor is invoked with the new operator. 38
  39. OOP: new operator • new creates a proper object (a generic object for user-defined constructors). • It takes a prototype from a constructor object and assigns it to the newly created object (this step cannot be done in any other way). • It passes the object as a context to a constructor. 39
  40. OOP: delegate • Now we can write a generic delegate: var delegate = (function(){ function temp(){} // it’ll hold a prototype reference return function(obj){ temp.prototype = obj; // saving a prototype var t = new temp(); // new object is delegated temp.prototype = null; // avoid a memory leak return t; }; })(); 40
  41. OOP: using delegate I var a = { hello: function(){ console.log(“Hello!”); }, zen: function(){ console.log(“O-O-OM”); } }; a.hello(); // Hello! var b = delegate(a); b.hello(); // Hello! b.hello = function(){ console.log(“Huh?”); }; a.hello(); // Hello! b.hello(); // Huh? 41
  42. OOP: using delegate II var c = delegate(b); a.hello(); // Hello! b.hello(); // Huh? c.hello(); // Huh? c.hello = function(){ console.log(“HI!!!”); }; a.hello(); // Hello! b.hello(); // Huh? c.hello(); // HI!!! delete c.hello; c.hello(); // Huh? 42
  43. OOP: advanced I • We just saw how we can organize our code using the single inheritance. • Many JS libraries provide OOP helpers: • An analog of delegate(). • A mix in procedure, which adds properties of one object to another. 43
  44. OOP: advanced II • dojo.declare() provides: • Multiple inheritance based on class linearization (using C3 MRO). • Chaining for constructors and regular methods. • Simple inherited() calls to augment an existing functionality. 44
  45. OOP: advanced III • This is a big topic, which we can discuss some other time. 45
  46. AOP Important aspects. 46
  47. AOP: short intro I • Aspect-oriented programming pays attention to cross-cutting concerns implemented as advices, which can be applied to pointcuts. • Pointcuts define “events” in our program where we can insert some extra code. 47
  48. AOP: short intro II • Examples of cross-cutting concerns: • Time/profile a function call. • Put all newly constructed objects in a list so we can iterate over them, remove them on destruction. • Cache results of an expensive pure function, and reuse them. 48
  49. AOP: short intro III • All examples demonstrate common things: • Code required to perform an advice does not depend on a nature of functions/objects it operates on. • AOP is just another way to structure you code. 49
  50. AOP in JavaScript • We can reliably intercept one thing: a method call. • In most cases it is more than enough for practical programmers. • All advice types can be implemented: • before, around, after, afterReturning, afterThrowing. 50
  51. AOP: toy example I • Let’s implement the “afterReturning” advice: function attachAfterReturning(obj, name, advice){ var old = obj[name]; obj[name] = function(){ var result = old.apply(this, arguments); advice.call(this, result); return result; }; } 51
  52. AOP: toy example II • Let’s implement the “before” advice: function attachBefore(obj, name, advice){ var old = obj[name]; obj[name] = function(){ advice. apply(this, arguments); return old.apply(this, arguments); }; } 52
  53. AOP: toy example III • Let’s implement the “around” advice: function attachAround(obj, name, advice){ var old = obj[name]; obj[name] = function(){ return advice.call(this, arguments, old); }; } 53
  54. AOP: advice example I • Simple tracer as “around” advice: var tracer = (function(){ var stack = []; return function(args, old){ console.log(“=> start”); stack.push(new Date().getTime()); var result = old.apply(this, args); var ms = new Date().getTime() - stack.pop(); console.log(“<= finish: “ + ms); return result; }; })(); 54
  55. AOP: using tracer var fact = { fact: function(n){ return n < 2 ? 1 : n * this.fact(n); } }; attachAround(fact, “fact”, tracer); fact.fact(3); // prints: // => start // => start // => start // <= finish: XX // <= finish: YY // <= finish: ZZ 55
  56. AOP: advice example II • Simple 1-arg memoization as two advices: var memoizer = function(){ var cache = {}; var memoizer = function(args, old){ var arg = args[0]; if(arg in cache){ return cache[arg]; } return cache[arg] = old.call(this, arg); }; memoizer.clear = function(){ cache = {}; }; return memoizer; }; 56
  57. AOP: using memoizer var fact = { fact: function(n){ return n < 2 ? 1 : n * this.fact(n); } }; var mem = memoizer(); attachAround(fact, “fact”, mem); console.log(fact.fact(55)); // repeated calculations will be very fast: console.log(fact.fact(60)); // “forget” previously calculated values mem.clear(); 57
  58. AOP and OOP I • There are some parallels between AOP and OOP: • Method chaining can be imagined as advices: • Constructors are chained using “after” advices. • Destructors are chained using “before”. 58
  59. AOP and OOP II • Super calls (inherited() calls) can be represented as “around” advice. • These similarities are not by chance. They reflect fundamental properties of OOP expressed in AOP terms. 59
  60. More on AOP • I wrote a blog post about AOP in JS and how it is implemented in Dojo: • http://lazutkin.com/blog/2008/may/18/ aop-aspect-javascript-dojo/ 60
  61. Intermediate stop • …and I ran out of time. • Next month we will talk about: • Functional programming (FP). • Domain-specific languages (DSL). • How JavaScript supports code generation (CG) techniques. 61
  62. About me • I am an independent software developer. • My web site: • http://lazutkin.com • Follow me on Tweeter: • http://twitter.com/uhop 62

×