SlideShare uma empresa Scribd logo
1 de 23
Baixar para ler offline
LEARNING FROM LIBRARIES
|Trevor Landau @trevor_landau
ABOUT
WHAT LIBS?
WHAT DID I MAKE?
function Collection() {}
JQUERY
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
LENGTH
Collection.prototype = {
length: 0
};
var c = new Collection;
Array.prototype.push.call(c, 1, 2);
log(c.length); // 2
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
BACKBONE
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]
ON && TRIGGER
c.on('push', function () {
log('push event', arguments); // 4, 5, 6
});
c.push(4, 5, 6);
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;
}
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;
}
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;
};
});
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]'
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]];
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);
}
};
LET'S SEE IT IN THE API
function Collection(args) {
// Accept different types
args = this._toArray(args) || [];
pApply(args, 'push', this);
}
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;
}
SHOULD.JS
GET
Collection.prototype = {
get size() {
return this.length;
},
get json() {
return JSON.stringify(this);
}
};
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;
}
});
});
THE END
https://github.com/landau/learningfromlibraries

Mais conteúdo relacionado

Mais procurados

modern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquerymodern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jqueryAdam Zygadlewicz
 
Menguak Misteri Module Bundler
Menguak Misteri Module BundlerMenguak Misteri Module Bundler
Menguak Misteri Module BundlerRiza Fahmi
 
Python codigo graficas
Python codigo graficasPython codigo graficas
Python codigo graficasBrayan Kalaka
 
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo Switch
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo SwitchSaints Row on the Go - Bringing Saints Row The Third to the Nintendo Switch
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo SwitchJohannes Kuhlmann
 
[KOSSA] C++ Programming - 14th Study - template
[KOSSA] C++ Programming - 14th Study - template[KOSSA] C++ Programming - 14th Study - template
[KOSSA] C++ Programming - 14th Study - templateSeok-joon Yun
 
Matlab: Вычисление значения выражения
Matlab: Вычисление значения выраженияMatlab: Вычисление значения выражения
Matlab: Вычисление значения выраженияDmitry Bulgakov
 

Mais procurados (20)

Triangle
TriangleTriangle
Triangle
 
Bifurcaciones (Ejemplo)
Bifurcaciones (Ejemplo)Bifurcaciones (Ejemplo)
Bifurcaciones (Ejemplo)
 
modern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquerymodern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquery
 
Passato
PassatoPassato
Passato
 
Menguak Misteri Module Bundler
Menguak Misteri Module BundlerMenguak Misteri Module Bundler
Menguak Misteri Module Bundler
 
Md5
Md5Md5
Md5
 
Aman
AmanAman
Aman
 
Python codigo graficas
Python codigo graficasPython codigo graficas
Python codigo graficas
 
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo Switch
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo SwitchSaints Row on the Go - Bringing Saints Row The Third to the Nintendo Switch
Saints Row on the Go - Bringing Saints Row The Third to the Nintendo Switch
 
الكود 2 (1)
الكود 2 (1)الكود 2 (1)
الكود 2 (1)
 
Img1
Img1Img1
Img1
 
[KOSSA] C++ Programming - 14th Study - template
[KOSSA] C++ Programming - 14th Study - template[KOSSA] C++ Programming - 14th Study - template
[KOSSA] C++ Programming - 14th Study - template
 
All set1
All set1All set1
All set1
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Matlab: Вычисление значения выражения
Matlab: Вычисление значения выраженияMatlab: Вычисление значения выражения
Matlab: Вычисление значения выражения
 
Librerias de c++
Librerias de c++Librerias de c++
Librerias de c++
 
Ugd9 c 7644
Ugd9 c 7644Ugd9 c 7644
Ugd9 c 7644
 
Java Week7 Notepad
Java Week7   NotepadJava Week7   Notepad
Java Week7 Notepad
 
2010 jan 11
2010 jan 112010 jan 11
2010 jan 11
 
Kruskal algorithm
Kruskal algorithmKruskal algorithm
Kruskal algorithm
 

Mais de Hakka Labs

Always Valid Inference (Ramesh Johari, Stanford)
Always Valid Inference (Ramesh Johari, Stanford)Always Valid Inference (Ramesh Johari, Stanford)
Always Valid Inference (Ramesh Johari, Stanford)Hakka Labs
 
DataEngConf SF16 - High cardinality time series search
DataEngConf SF16 - High cardinality time series searchDataEngConf SF16 - High cardinality time series search
DataEngConf SF16 - High cardinality time series searchHakka Labs
 
DataEngConf SF16 - Data Asserts: Defensive Data Science
DataEngConf SF16 - Data Asserts: Defensive Data ScienceDataEngConf SF16 - Data Asserts: Defensive Data Science
DataEngConf SF16 - Data Asserts: Defensive Data ScienceHakka Labs
 
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast Data
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast DataDatEngConf SF16 - Apache Kudu: Fast Analytics on Fast Data
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast DataHakka Labs
 
DataEngConf SF16 - Recommendations at Instacart
DataEngConf SF16 - Recommendations at InstacartDataEngConf SF16 - Recommendations at Instacart
DataEngConf SF16 - Recommendations at InstacartHakka Labs
 
DataEngConf SF16 - Running simulations at scale
DataEngConf SF16 - Running simulations at scaleDataEngConf SF16 - Running simulations at scale
DataEngConf SF16 - Running simulations at scaleHakka Labs
 
DataEngConf SF16 - Deriving Meaning from Wearable Sensor Data
DataEngConf SF16 - Deriving Meaning from Wearable Sensor DataDataEngConf SF16 - Deriving Meaning from Wearable Sensor Data
DataEngConf SF16 - Deriving Meaning from Wearable Sensor DataHakka Labs
 
DataEngConf SF16 - Collecting and Moving Data at Scale
DataEngConf SF16 - Collecting and Moving Data at Scale DataEngConf SF16 - Collecting and Moving Data at Scale
DataEngConf SF16 - Collecting and Moving Data at Scale Hakka Labs
 
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQ
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQDataEngConf SF16 - BYOMQ: Why We [re]Built IronMQ
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQHakka Labs
 
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...Hakka Labs
 
DataEngConf SF16 - Three lessons learned from building a production machine l...
DataEngConf SF16 - Three lessons learned from building a production machine l...DataEngConf SF16 - Three lessons learned from building a production machine l...
DataEngConf SF16 - Three lessons learned from building a production machine l...Hakka Labs
 
DataEngConf SF16 - Scalable and Reliable Logging at Pinterest
DataEngConf SF16 - Scalable and Reliable Logging at PinterestDataEngConf SF16 - Scalable and Reliable Logging at Pinterest
DataEngConf SF16 - Scalable and Reliable Logging at PinterestHakka Labs
 
DataEngConf SF16 - Bridging the gap between data science and data engineering
DataEngConf SF16 - Bridging the gap between data science and data engineeringDataEngConf SF16 - Bridging the gap between data science and data engineering
DataEngConf SF16 - Bridging the gap between data science and data engineeringHakka Labs
 
DataEngConf SF16 - Multi-temporal Data Structures
DataEngConf SF16 - Multi-temporal Data StructuresDataEngConf SF16 - Multi-temporal Data Structures
DataEngConf SF16 - Multi-temporal Data StructuresHakka Labs
 
DataEngConf SF16 - Entity Resolution in Data Pipelines Using Spark
DataEngConf SF16 - Entity Resolution in Data Pipelines Using SparkDataEngConf SF16 - Entity Resolution in Data Pipelines Using Spark
DataEngConf SF16 - Entity Resolution in Data Pipelines Using SparkHakka Labs
 
DataEngConf SF16 - Beginning with Ourselves
DataEngConf SF16 - Beginning with OurselvesDataEngConf SF16 - Beginning with Ourselves
DataEngConf SF16 - Beginning with OurselvesHakka Labs
 
DataEngConf SF16 - Routing Billions of Analytics Events with High Deliverability
DataEngConf SF16 - Routing Billions of Analytics Events with High DeliverabilityDataEngConf SF16 - Routing Billions of Analytics Events with High Deliverability
DataEngConf SF16 - Routing Billions of Analytics Events with High DeliverabilityHakka Labs
 
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...Hakka Labs
 
DataEngConf SF16 - Methods for Content Relevance at LinkedIn
DataEngConf SF16 - Methods for Content Relevance at LinkedInDataEngConf SF16 - Methods for Content Relevance at LinkedIn
DataEngConf SF16 - Methods for Content Relevance at LinkedInHakka Labs
 
DataEngConf SF16 - Spark SQL Workshop
DataEngConf SF16 - Spark SQL WorkshopDataEngConf SF16 - Spark SQL Workshop
DataEngConf SF16 - Spark SQL WorkshopHakka Labs
 

Mais de Hakka Labs (20)

Always Valid Inference (Ramesh Johari, Stanford)
Always Valid Inference (Ramesh Johari, Stanford)Always Valid Inference (Ramesh Johari, Stanford)
Always Valid Inference (Ramesh Johari, Stanford)
 
DataEngConf SF16 - High cardinality time series search
DataEngConf SF16 - High cardinality time series searchDataEngConf SF16 - High cardinality time series search
DataEngConf SF16 - High cardinality time series search
 
DataEngConf SF16 - Data Asserts: Defensive Data Science
DataEngConf SF16 - Data Asserts: Defensive Data ScienceDataEngConf SF16 - Data Asserts: Defensive Data Science
DataEngConf SF16 - Data Asserts: Defensive Data Science
 
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast Data
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast DataDatEngConf SF16 - Apache Kudu: Fast Analytics on Fast Data
DatEngConf SF16 - Apache Kudu: Fast Analytics on Fast Data
 
DataEngConf SF16 - Recommendations at Instacart
DataEngConf SF16 - Recommendations at InstacartDataEngConf SF16 - Recommendations at Instacart
DataEngConf SF16 - Recommendations at Instacart
 
DataEngConf SF16 - Running simulations at scale
DataEngConf SF16 - Running simulations at scaleDataEngConf SF16 - Running simulations at scale
DataEngConf SF16 - Running simulations at scale
 
DataEngConf SF16 - Deriving Meaning from Wearable Sensor Data
DataEngConf SF16 - Deriving Meaning from Wearable Sensor DataDataEngConf SF16 - Deriving Meaning from Wearable Sensor Data
DataEngConf SF16 - Deriving Meaning from Wearable Sensor Data
 
DataEngConf SF16 - Collecting and Moving Data at Scale
DataEngConf SF16 - Collecting and Moving Data at Scale DataEngConf SF16 - Collecting and Moving Data at Scale
DataEngConf SF16 - Collecting and Moving Data at Scale
 
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQ
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQDataEngConf SF16 - BYOMQ: Why We [re]Built IronMQ
DataEngConf SF16 - BYOMQ: Why We [re]Built IronMQ
 
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...
DataEngConf SF16 - Unifying Real Time and Historical Analytics with the Lambd...
 
DataEngConf SF16 - Three lessons learned from building a production machine l...
DataEngConf SF16 - Three lessons learned from building a production machine l...DataEngConf SF16 - Three lessons learned from building a production machine l...
DataEngConf SF16 - Three lessons learned from building a production machine l...
 
DataEngConf SF16 - Scalable and Reliable Logging at Pinterest
DataEngConf SF16 - Scalable and Reliable Logging at PinterestDataEngConf SF16 - Scalable and Reliable Logging at Pinterest
DataEngConf SF16 - Scalable and Reliable Logging at Pinterest
 
DataEngConf SF16 - Bridging the gap between data science and data engineering
DataEngConf SF16 - Bridging the gap between data science and data engineeringDataEngConf SF16 - Bridging the gap between data science and data engineering
DataEngConf SF16 - Bridging the gap between data science and data engineering
 
DataEngConf SF16 - Multi-temporal Data Structures
DataEngConf SF16 - Multi-temporal Data StructuresDataEngConf SF16 - Multi-temporal Data Structures
DataEngConf SF16 - Multi-temporal Data Structures
 
DataEngConf SF16 - Entity Resolution in Data Pipelines Using Spark
DataEngConf SF16 - Entity Resolution in Data Pipelines Using SparkDataEngConf SF16 - Entity Resolution in Data Pipelines Using Spark
DataEngConf SF16 - Entity Resolution in Data Pipelines Using Spark
 
DataEngConf SF16 - Beginning with Ourselves
DataEngConf SF16 - Beginning with OurselvesDataEngConf SF16 - Beginning with Ourselves
DataEngConf SF16 - Beginning with Ourselves
 
DataEngConf SF16 - Routing Billions of Analytics Events with High Deliverability
DataEngConf SF16 - Routing Billions of Analytics Events with High DeliverabilityDataEngConf SF16 - Routing Billions of Analytics Events with High Deliverability
DataEngConf SF16 - Routing Billions of Analytics Events with High Deliverability
 
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...
DataEngConf SF16 - Tales from the other side - What a hiring manager wish you...
 
DataEngConf SF16 - Methods for Content Relevance at LinkedIn
DataEngConf SF16 - Methods for Content Relevance at LinkedInDataEngConf SF16 - Methods for Content Relevance at LinkedIn
DataEngConf SF16 - Methods for Content Relevance at LinkedIn
 
DataEngConf SF16 - Spark SQL Workshop
DataEngConf SF16 - Spark SQL WorkshopDataEngConf SF16 - Spark SQL Workshop
DataEngConf SF16 - Spark SQL Workshop
 

Learning from JavaScript Libraries by Trevor Landau

  • 1. LEARNING FROM LIBRARIES |Trevor Landau @trevor_landau
  • 4. WHAT DID I MAKE? function Collection() {}
  • 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
  • 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; }
  • 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; } }); });