Your SlideShare is downloading. ×
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
Learning from JavaScript Libraries by Trevor Landau
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

Learning from JavaScript Libraries by Trevor Landau

393

Published on

jQuery runs on approximately 50% of all websites and is the de facto standard for DOM manipulation. Most front end developers use it, but how well do they understand what's happening when they use the …

jQuery runs on approximately 50% of all websites and is the de facto standard for DOM manipulation. Most front end developers use it, but how well do they understand what's happening when they use the API? How does a library take on the problems it solves? What are the reasons behind some of the techniques it uses? Observing the code under the hood of a library/framework is a fantastic way to become a better developer and thereby user of that library/framework. Better understanding of design patterns in some of the most popular libraries can open opportunities to contribute and be a better open source citizen.

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
393
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
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. LEARNING FROM LIBRARIES |Trevor Landau @trevor_landau
  • 2. ABOUT
  • 3. WHAT LIBS?
  • 4. WHAT DID I MAKE? function Collection() {}
  • 5. JQUERY
  • 6. NOCONFLICT window.Collection = 'foo'; var oldC = window.Collection; Collection.noConflict = function () { window.Collection = oldC; return Collection; }; var C = Collection.noConflict(); log(typeof C, typeof Collection); // object, string
  • 7. LENGTH Collection.prototype = { length: 0 }; var c = new Collection; Array.prototype.push.call(c, 1, 2); log(c.length); // 2
  • 8. CONSTRUCTOR FACADE function Collection(args) { if (args && !Array.isArray(args) && arguments.length >= 0) { if (typeof args.toArray === 'function') { args = args.toArray(); } else { args = __slice.apply(arguments); } } else { args = []; } if (args.length) Array.prototype.push.apply(this, args); } var c = new Collection([1,2,3]); var c2 = new Collection(1,2,3); var c3 = new Collection({ toArray: function () { return [1,2,3]; } }); log(c.length, c2.length, c3.length); // 3, 3, 3
  • 9. BACKBONE
  • 10. ALL ARRAY BELONG TO US function Collection(args) { this.push.apply(this, args); } var omit = ['length', 'constructor', 'toString', 'toLocalString']; Object.getOwnPropertyNames(arrProto).forEach(function (fn) { if (omit.indexOf(fn) > -1) return; Collection.prototype[fn] = function () { var args = __slice.call(arguments); return arrProto[fn].apply(this, args); }; }); var c = new Collection([1,2,3]); log(c.length); // 3 log(c.unshift(0)); // [0, 1, 2, 3]
  • 11. ON && TRIGGER c.on('push', function () { log('push event', arguments); // 4, 5, 6 }); c.push(4, 5, 6);
  • 12. ON on: function (name, fn, ctx) { this._events = this._events || {}; var events = this._events[name] || (this._events[name] = []); events.push({ fn: fn, ctx: ctx || this }); return this; }
  • 13. TRIGGER trigger: function (name) { if (!this._events) return this; var args = __slice.call(arguments, 1); var events = this._events[name]; if (events) { events.forEach(function (ev) { ev.fn.apply(ev.ctx, args); }); } return this; }
  • 14. LETS SEE IN OUR API Object.getOwnPropertyNames(arrProto).forEach(function (fn) { if (omit.indexOf(fn) > -1) return; Collection.prototype[fn] = function () { var args = __slice.call(arguments); var ret = arrProto[fn].apply(this, args); this.trigger(fn, ret); return ret; }; });
  • 15. TOJSON Collection.prototype.toJSON = function () { return this.map(function (val) { return val; }); }; var c = new Collection(1,2,3); // Without method JSON.stringify(c); // '{"0":1,"1":2,"2":3}' - will also contain other props... // With method JSON.stringify(c); // '[1,2,3]'
  • 16. UNDERSCORE Collection.zip = function () { var args = __slice.call(arguments); var lengths = args.map(function (c) { return c.length; }); var length = Math.max.apply(Math, lengths); var results = new Array(length); var map = function (c) { return c[i]; }; for (var i = 0; i < length; i += 1) { results[i] = args.map(map); } return results; } var c = new Collection([1,2]); var c2 = new Collection([3,4]); console.log(Collection.zip(c, c2)); // [[1,3],[2,4]];
  • 17. ANGULAR http://jsperf.com/apply-vs-call-vs-invoke // performant apply var pApply = function (args, fn, ctx) { switch (args.length) { case 0: return ctx[fn](); case 1: return ctx[fn](args[0]); case 2: return ctx[fn](args[0], args[1]); case 3: return ctx[fn](args[0], args[1], args[2]); case 4: return ctx[fn](args[0], args[1], args[2], args[3]); case 5: return ctx[fn](args[0], args[1], args[2], args[3], args[4]); ... case 10: return ctx[fn](args[0], args[1], args[2], args[3], args[4], args[5 default: return ctx[fn].apply(ctx, args); } };
  • 18. LET'S SEE IT IN THE API function Collection(args) { // Accept different types args = this._toArray(args) || []; pApply(args, 'push', this); }
  • 19. MOCHA Collection.prototype.repr = function () { var self = this; // override toJSON for repr purposes this.toJSON = null; var repr = JSON.stringify(this, function (key, val) { if (self === val || !isNaN(parseInt(key, 10))) { return val; } return void 0; }); // reset delete this.toJSON; return repr; }
  • 20. SHOULD.JS
  • 21. GET Collection.prototype = { get size() { return this.length; }, get json() { return JSON.stringify(this); } };
  • 22. DEFINEPROPERTY var omit = ['length', 'constructor', 'toString', 'toLocalString']; Object.getOwnPropertyNames(arrProto).forEach(function (fn) { if (omit.indexOf(fn) > -1) return; Object.defineProperty(Collection.prototype, fn, { value: function () { var args = __slice.call(arguments); var ret = arrProto[fn].apply(this, args); var evArgs = [fn, ret]; pApply(evArgs, 'trigger', this); return ret; } }); });
  • 23. THE END https://github.com/landau/learningfromlibraries

×