Your SlideShare is downloading. ×
Advanced JavaScript
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Advanced JavaScript

321
views

Published on

Some advanced topics, functinal approach, popular OO inheritance patterns.

Some advanced topics, functinal approach, popular OO inheritance patterns.


0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
321
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
9
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Language philosophy, advanced featuresADVANCED JAVASCRIPT Zsolt Mészárovics <EPAM>
  • 2. $ whoamiProgramming languages: Compiled, general purpose: Java; C/C++; Scala Scripting: JavaScript; Python; etc… Experimental: Go; Dart; CoffeeScriptRecent works (non-project, related to JS): NodeJS based stuff involving custom C++ extensions Closure Compiler / Closure Templates enhancements
  • 3. Agenda OO Inheritance patterns in JS, which one to use? Exploiting functional paradigm support Asynchronity in JS (still) common pitfalls, how to avoid them? Agenda is based on my observations during every day work, working with 3rd party sources.
  • 4. OO & Inheritance Patterns Devs tend to trust various frameworks to construct classes with inheritance.Popular types (Crockford’s terms): „Pseudoclassical” „Power-constructor” or „Parasital”Trends: Avoiding new keyword Emulating private members with closures Assembling objects from prototypes „by hand”
  • 5. Pseudo-Classical PatternPopular types (Crockfod’s terms): „Pseudo-classical” „Power-Constructor” or „Parasital”Concerning trends: „Power constructors” – avoiding new keyword Emulating private members with closures Assembling objects from prototypes „by hand”
  • 6. Pseudo-Classical Example function Shape(x, y) { this.x = x; this.y = y; } Shape.prototype.move = function (x, y) { this.x += x; this.y += y; }; function Rectangle(x1, y1, x2, y2) { Shape.call(this, (x1 + x2) / 2, (y1 + y2) / 2); this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; } Rectangle.prototype = Object.create(Shape.prototype); // may poly Rectangle.prototype.area = function () { return (this.x2 - this.x1) * (this.y2 - this.y1); };
  • 7. Object.create Polyfill if (!Object.create) { Object.create = function (o) { if (arguments.length > 1) { throw new Error(properties not implemented); } function F() {} F.prototype = o; return new F(); }; }
  • 8. Power-Constructor Example function Shape(x, y) { return { x: x, y: y, move: function (x, y) { this.x += x; this.y += y; } }; } function Rectangle(x1, y1, x2, y2) { var self = Shape((x1 + x2) / 2, (y1 + y2) / 2); self.x1 = x1; self.x2 = x2; self.y1 = y1; self.y2 = y2; self.area = function () { return (self.x2 - self.x1) * (self.y2 - this.y1); }; return self; }
  • 9. Difference of Resulting ObjectsPrototype chain (__proto__): „Pseudo-Classical” „Power-constructor” Rectangle Rectangle + Shape Shape Object Object Shape Object • layered structure, head object • flat structure, every head has only instance members object has all members • Instantiated with new • new keyword is optional keyword
  • 10. Which One is Better? Power-Constructor pattern is extremely popular. A lot of frameworks using it, including jQuery. Do we need privates? – not really Performance?Demo time! Let’s evaluate performance with a particle system.
  • 11. ConclusionDespite a little bit more verbose, might look not as self-contained thanother variants, Pseudo-Classical inheritance is the way to go.Advantages: Way batter performance, especially at large number of instances Better IDE recognition Better tooling (Closure-Compiler friendly)
  • 12. Functional Paradigm: Higher Order FunctionsFunctions could be passed as arguments, and could be returned by otherfunctions as return values.Functions are threated as first-class values.This provides a flexible way to compose programs.
  • 13. Example:Take the sum of the integers between a and b: // sum of integers between a and b function sumInts(a, b) { var sum = 0, i; for (i = a; i <= b; i += 1) { sum += i; } return sum; }Take the sum of the cubes of all integers between a and b: function cube(n) { return Math.pow(n, 3); } function sumCubes(a, b) { var sum = 0, i; for (i = a; i <= b; i += 1) { sum += cube(i); } return sum; }
  • 14. Example (continued) function factorial(n) { var i, f = 1; for (i = 2; i <= n; i += 1) { f *= i; } return f; } function sumFactorials(a, b) { var sum = 0, i; for (i = a; i <= b; i += 1) { sum += factorial(i); } return sum; }
  • 15. Advanced version using higher-order functionsA generic sum: function sum(f, a, b) { var sum = 0, i; for (i = a; i <= b; i += 1) { sum += f(i); } return sum; }Rewritten special cases: function identity(n) { return n; } sumInts = function (a, b) { return sum(identity, a, b); }; sumCubes = function (a, b) { return sum(cube, a, b); }; sumFactorials = function (a, b) { return sum(factorial, a, b); };Taking functions as parameters, but still a lot of redundancy here…
  • 16. More advanced version, removed redundancyLet’s rewrite sum to return a function: function sum(fn) { return function (a, b) { var sum = 0, i; for (i = a; i <= b; i += 1) { sum += fn(i); } return sum; }; }So specific cases could be written as: sumInts = sum(identity); sumCubes = sum(cube); sumFactorials = sum(factorial);Or could be invoked without the middle-man: // equivalent to sumCubes sum(cube)(3, 5); // sum of the halves of integers between a and b sum(function (n) { return Math.round(n / 2); })(3, 5);
  • 17. AsynchronicityJS is… Event driven Single threaded (setTimeout doesn’t do the trick)  Long running code could block execution, UI responsiveness Standard APIs rely on call-backs  They are often nested multiple levels  Hard to debug: reading the call-stack is hard; exceptions might not get propagated up to the initiator  „Pyramid of Doom”!
  • 18. Difficulties with Call-backs„Pyramid of doom”When the code marches to the right faster than it marches forward: step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });This is sequential, what if step3 could be executed when both step1 andstep2 are completed, but those two steps doesn’t depend on each other?
  • 19. Difficulties with Call-backs (continued)Synchronizing multiple call-backs var callbackACompleted = false; var callbackBCompleted = false; function callbackA(result) { // process result callbackACompleted = true; if (callbackBCompleted) { done(); } } function callbackB(result) { // process result callbackBCompleted = true; if (callbackACompleted) { done(); } } function done() { // things to do when boot callbacks completed their jobs } processA(params, callbackA); processB(params, callbackB);
  • 20. Deferred objects / Promises / Futures Designed to solve exactly these problems Under used, not widely knownAPI done() then() A promise is the stripped down Promise version of the deferred instance, fail() Deferred doesn’t contain any state mutator always() methods. resolve() reject()Usage: a task creates a deferred object, and resolves (or fails it) later bycalling .resolve() / .reject(). Clients use promise, which doesn’t provide statemanipulation, just change subscription methods.
  • 21. Demo
  • 22. PitfallsArray Deleting delete arr[2]; // [1, 3, undefined × 1, 29, 45, 51] arr.splice(2, 1); // ok! [1, 3, 29, 45, 51] Never attempt to remove an element from an array with delete, use splice. Sorting arr = [1, 3, 24, 29, 45, 51]; arr.sort(); // [1, 24, 29, 3, 45, 51] arr.sort(function (x, y) {return x > y;}); // ok What happened? Don’t relay on default sort functionality; implement getComparator() -> function for objects.
  • 23. Pitfalls (continued)Number Conversion +"08"; // ok (8) +new Date; // .valueOF() Number("08"); // same as + parseInt("08"); // 0 why? parseInt("ff", 16); // 256 Prefer the + unary operator, you may implement valueOf(), always provide radix for parseInt()!Typeof // typeof typeof array === "object"; // Array.isArray() (polyfill) typeof null === "object"; // spec error :( Worst is typeof null, it returns „object” as a result of an early language specification.