Skip to content

Instantly share code, notes, and snippets.

@graph1zzlle
Last active December 14, 2015 19:29
Show Gist options
  • Save graph1zzlle/5137057 to your computer and use it in GitHub Desktop.
Save graph1zzlle/5137057 to your computer and use it in GitHub Desktop.
Notes I have taken throughout my javascript learning, hope it will help someone :0

Notes are actually on:

  • callbacks
  • objects
  • prototype
  • namespaces
/*
* CALLBACKS
*/
// Callbacks functions are widely used for async execution, event listener /
// event hanlder
// A callback function is a function that is passed to another function
// as a parameter, and the callback is called inside this another function.
// As we know, closures have access to the containing functions scope,
// so the callback function can access the containing functions variables,
// and even the variables from the global scope.
/* I. ANONYMOUS CALLBACK */
var a = ["a", "b", "c"];
a.forEach(function (value, index) {// we have passed an anonymous functions as parameter
var x = index + 1;
console.log(x + ". " + value);
});
/* II. CALLBACK WITH NAMED FUNCTION */
function getDataAndProcess(callback){
var data = "Hello";
if(callback && typeof(callback) === "function") { // ensure that the callback is actually a function
return callback(data);
}
}
function process (data) {
return data.substr(0,2);
}
var processedData = getDataAndProcess(process);
console.log(processedData); // "He"
// if we use the this object in a callback function, we have to modify
// how the callback function is executed to preserve the this object context.
// we need to be careful aswell for the 'callback hell' effect,
// e.g many nested callbacks. Better name the function and sctructure the code.
/*
* OBJECTS
*/
// Javascript fundamental datatype is object. Any value other than string, number, boolean values,
// null or undefined is an object.
// Every objects has class, prototype and extensible attributes
/* I. OBJECTS ARE MUTABLE AND MANIPULATED BY REFERENCE */
var x = { x:2 };
var y = x; // y holds a reference on x, not a copy
y.y = 2;
console.log(x); // Object {x: 2, y: 2}
/* Create an object */
var empty = {}; // empty object
var track = { // literal way, you can also nest properties
artist: "netsky",
title: "Your Way",
label: "Hospital Records"
}
var empty = new Object(); // = {}; create an object with new
var array = new Array(); // = [];
var obj = Object.create(empty); // first arg take the prototype of empty to inject in obj,
// can use a second arg to define the properties of obj
/* II. TEST AN OBJECT PROPERTY */
"artist" in track // true
track.hasOwnProperty("artist") // true, would be false if "artist" was an inherited property
/* III. QUERY AN OBJECT PROPERTY */
var title = track["title"]; // access properties with associative array, where the property name is a string
var label = track.label; // or dot notation (.)
console.log(track.lyrics) // undefined, but doesn't throw an exception
var lyricsLen = // this will throw a typeError exception, because lyrics is undefined.
track.lyrics.length;
var lyricsLen = // this is a concise way of protecting property access, can be done with if {} aswell
track && track.lyrics && track.lyrics.length;
var book = { // Considering the following code, I find access properties with associative array
author0: "a", // useful in this case. You can't do this with the . expression, because the property
author1: "b", // is an identifier, not a string.
author2: "c"
}
var enumAuthors = function(book) {
var authorCounter = 0;
for(property in book) { // enumerate properties !
if(property.indexOf("author") !== -1 ) {
authorCounter++;
}
}
var authors = "";
for(var i = 0; i < authorCounter; i++) {
if(i == authorCounter - 1) {
authors += book["author" + i];
} else {
authors += book["author" + i] + ", ";
}
}
console.log(authors);
}
enumAuthors(book); // a, b, c
// We have seen that you can enumerate properties with a simple for loop,
// but ES5 define the following
Object.keys(track); // ["artist", "title", "label"] array of the enumerable own properties
Object.getOwnPropertyNames(track); // same as .keys(), but return an array of all the own properties
// it makes sense because ES5 provide a way to make a property non-enumerable
/* IV. DELETE AN OBJECT PROPERTY */
// the delete operator deletes the object OWN properties, not inherited ones.
// for doing so, delete the property in the prototype. Be careful, it affect
// every objects that inherits from that prototype. side-effect !
delete track.label;
console.log(track); // Object {artist: "netsky", title: "Your Way"}
// You can't delete properties like the prototype, because they are read only
/* V. OBJECT SERIALIZATION/DESERIALIZATION */
var s = JSON.stringify(track); // NaN, Infinity, -Infinity serialize to null
var ptrack = JSON.stringify(s); // Date are serialized to ISO date string
// Function, RegExp and Error objects and undefinined
// can't be serialized.
/* VI. OBJECT METHODs REF */
toString();
toLocaleString(); // format date and number according to local settings
toJSON(); // JSON.stringify() looks for a toJSON() method on any object passed
valueOf();
/*
* PROTOTYPE
*/
// WARNING: for better understanding of prototype, please don't give a single fuck
// to the pseudo __proto__ property of Mozilla JS implementation, it is non-standard.
/* I. PROTOTYPE PROPERTY */
// There is a prototype property on every function, empty by default
// and not enumerable (no for/in loop)
var getHello = function (){
return "Hello";
}
console.log(getHello.prototype) // Object {};
// That said, Firefox and most versions of Chrome have a
// __proto__ wrapper property that allow acess. don't use it
// We use the prototype property to apply inheritance
function pdfDoc(doc){
this.doc = doc;
}
pdfDoc.prototype.print = function () {
console.log(this.doc);
}
var pdfDoc = new pdfDoc(doc);
pdfDoc.print();
/* II. Prototype attribute */
// The prototype attribute is set when an object is created.
// Prototype Attribute for Ojbects created with literal or new Object
var x = { x:1 };
var y = new Object(x);
x.isPrototypeOf(y); // true
Object.prototype.isPrototypeOf(y); // true
x.prototype // undefined, wtf ?
// because when creating like {x:1}, you're actually
// creating an instance of the Object constructor
Object.getPrototypeOf(x); // Object {}
// because the prototype of the Object constructor
// is an Object. The Object prototype is itself
// an object
// we can conclude that constructors have .prototype and instances
// have Object.getPrototypeOf()
Object.getOwnPropertyNames(Object.getPrototypeOf(x));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty",
// "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__", "__lookupGetter__",
// "__defineSetter__", "__lookupSetter__"]
// We can see here that all objects created with literals or object ctor
// inherits from Object.prototype.
/*
* NAMESPACES
*/
// So this is my attempt at creating clean, self-injecting namespace in javascript
// using IIFE (Immediately-invoked function expression).
// Be aware that now it seems there is plenty of things and lib to deal
// with this like requireJS / CommonJS
;(function(ns) {
var calc = (function(ns){
ns.addition = function() {
var total = 0;
for(var i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
};
ns.multiply = function() {
var total = 1;
for(var i = 0; i < arguments.length; i++) {
total *= arguments[i];
}
return total;
};
}) (ns.calc = ns.calc || {});
}) (window.myLib = window.myLib || {});
console.log(myLib.calc.addition(1,2,3,4)); // 10
console.log(myLib.calc.multiply(1,2,3,4)); // 24
console.log(myLib); // Object {calc: Object}
console.log(myLib.calc); // Object {addition: function, multiply: function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment