J.D Nicholls
Founding Full-Stack Web3 Engineer at @baxusco | Digital nomad 🎒 | Mentor 👨🏫 | Speaker 🗣️ | Developer 👨💻 | Creator of @proyecto26 #opensource #developer
// Non-strict code...
(function(){
"use strict";
// Define your library strictly...
})();
// Non-strict code...
Guide here
"Can't have "with" in strict mode"
(function($) {
"use strict";
//Your code using jQuery
})(jQuery);
var MyLibraryName = MyLibraryName || {};
MyLibraryName.invalidElements = (function($) {
"use strict";
var _nameClass = "myLibraryInvalidElement"; //Private Property
var _getnameClass = function() { //Private Method
// Do private stuff, or build internal.
return _nameClass;
};
var _getElementsByClass = function() {
return $("."+ _getnameClass());
};
return {
version: "1.0.0", //constant
getElementsByClass: _getElementsByClass
};
})(jQuery);
//Extend namespace in other files...
//MyLibraryName.otherfunction = (function(){ ... })();
MyLibraryName.invalidElements.getElementsByClass()
void function(){
"use strict";
//Your code
};
for (i = 0; i < users.length; i++) {
console.log(users[i]);
}
var person = {fname:"John", lname:"Doe", age:25};
for (var x in person) {
console.log(x);
}
while (i < 10) {
console.log("The number is " + i);
i++;
}
do {
console.log("The number is " + i);
i++;
}
while (i < 10);
[ ]
{}
Guide here
if(undefined){ // => false
if(null){ // => false
if(false){ // => false
if(0){ // => false
if(""){ // => false
if(NaN){ // => false
if (true) // => true
if ({}) // => true
if ([]) // => true
if (42) // => true
if ("foo") // => true
if (new Date()) // => true
if(new Array() == false) { // => true
if(false == 0) { // => true
if(false == "") { // => true
if(0 == "") { // => true
if("0") // => true
if(NaN == NaN) { // => false
if(undefined == null) // => true
if(new Array() === false) { // => false
if(false === 0) { // => false
if(false === "") { // => false
if(0 === "") { // => false
if("0" === true) // => false
if(NaN === NaN) { // => false o.O
if(undefined === null) // => false
Links:
Link: J avascript The Good Parts - Page 26
"every function receives two additional parameters: this and arguments..."
function demo(name, year){
return arguments;
}
demo("Nicholls", 1991); // => ["Nicholls", 1991]
demo("Anonymous"); // => ["Anonymous"]
Link: Javascript The Good Parts - Page 32
var tryCatch = function (fn) {
try {
fn.apply(this, Array.prototype.slice.call(arguments, 1));
}
catch (ex) { /* eat please */ }
};
tryCatch(demo, "Juan", 1991); //https://gist.github.com/equisoide/de0acd127b4ecc2698eb
throw {
name: 'TypeError', //Type of the exception
message: 'Horribleee human!' //Descriptive message
//Add more properties...
};
function Error(){
return
{
status: true
};
}
typeof null == typeof [1,2,3]
(0.1 + 0.2) != 0.3 // => true
//Bad
"4" + 3
//Better
Number("4") + 3
parseInt("4") + 3
Link: J avascript The Good Parts - Page 23
typeof flight.number // 'number'
typeof flight.status // 'string'
typeof flight.arrival // 'object'
typeof flight.manifest // 'undefined'
typeof flight.toString // 'function'
typeof flight.constructor // 'function'
flight.hasOwnProperty('number') // true
flight.hasOwnProperty('constructor') // false
if (typeof(v) === "function") {
// do something
}
La reflexión es un proceso mediante el cual un programa es capaz de obtener información sobre si mismo y por tanto es capaz de auto modificarse en tiempo de ejecución.
Link: Javascript The Good Parts - Page 23 and 46
//For IE...
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
var Cat = function (name, age) {
this.name = name;
this.age = age;
};
var Siamese = function (color, colorEyes, name, age) {
Cat.call(this, name, age);
this.color = color;
this.color_eyes = colorEyes;
};
Siamese.prototype = Object.create(Cat.prototype);
Siamese.prototype.constructor = Siamese;
var cat = new Siamese("black", "green", "Little cat", 2);
Cat.prototype.run = function(){
console.log(this.name + " is running!!");
};
cat.run(); // => "Little cat is running!!"
Link: Javascript The Good Parts - Page 65
"JavaScript’s Regular Expression feature was borrowed from Perl"
//Validate Numbers
var pattern = /^\d+$/;
pattern.test("Juan") // => false
//Validate Emails
var pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
pattern.test("john.smith@gmail.com") // => tr4e
//But the grammar specified in RFC 5322 is too complicated for primitive regular expressions
//Validate Date (MM/DD/YYYY)/(MM-DD-YYYY)/(MM.DD.YYYY)/(MM DD YYYY)
/^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$/
//Validate HTML tag
/^<([a-z]+)([^<]+)*(?:>(.*)</1>|s+/>)$/
//Validate URL
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/
var Fenton = (function () {
function Customer(name) {
this.name = name;
}
Customer.prototype.greet: function () {
return this.name + ' says hi!';
};
function VipCustomer(name, discountPercentage) {
Customer.call(this, name);
this.discountPercentage = discountPercentage;
}
VipCustomer.prototype = new Customer();
VipCustomer.prototype.constructor = VipCustomer;
return {
Customer: Customer,
VipCustomer: VipCustomer
};
}());
var steve = new Fenton.Customer('Osman');
var todd = new Fenton.VipCustomer('Jorge', 10);
"use call to chain constructors for an object"
$("document").ready(function() {
//code code code
});
$(function() {
//code code code
});
The DOM is ready!
or
DOM Manipulation
//Selectors
$("#myinput") // => Get element by ID
$(".myinputs") // => Get elements by class
$("#myinput").val() // => get value from element
$("#myinput").val("example") // => set value to the element
$("#elem").attr("title", "My title") // => set an element's title attribute
$("#elem").css("color", "red") // => set an element's text color
//Hide elements
$("#elem").hide();
$("#elem").fadeOut();
$("body").fadeOut(1000, function(){
alert("finish hide element!");
});
//Insert HTML
$('#elem').html("<h1>Demo</h1>");
$('#elem').text("This is Sparta!");
$("#mydiv").addClass("gored");
$("#mydiv").removeClass("gored");
$("#mydiv").toggleClass("zclass");
$("<div></div>").appendTo("#myParent");
$("#myParent").prepend("<div></div>");
$("#myParent").append("<div></div>");
$("#myParent").before("<div></div>");
$("#myParent").after("<div></div>");
$("#other").load("otherpage.html");
//Find elements
$('#class-container .class') //Modern browsers, QuerySelectorAll like CSS
$('.class', '#class-container')
$parent.find(".child") //Better for all browsers
$parent.children(); //Direct children
$("#mydiv").animate({
opacity: 0.25,
left: "+=50",
height: "toggle"
}, 5000, function() {
// Animation complete.
});
var arr = [1, 2, 3, 4, 5, 6];
var filter = $.grep(arr, function(item, index) {
return item > 3;
});
console.log(filter); // [4, 5, 6]
var arr = [1, 2, 3, 4, 5, 6];
var filter = $.map(arr, function(item, index) {
return item + ", position: "+ index;
});
console.log(filter); // ["1, position: 0", "2, position: 1", ...]
The best practices
//Cache your selectors in variables
var $myinput = $("#myinput");
$myinput.css("color", "red");
$myinput.delay(2000).fadeOut(1000);
//Chaining => shorter is better! :)
$myinput.css("color", "red")
.delay(2000)
.fadeOut(1000);
//Append once
var girls = ["Andrea", "Yuliana", "Sorel", "Erica"];
var girlsHtml = "";
$.each(girls, function(index, value) {
girlsHtml += "<li id=" + index + ">" + value + "</li>"
});
$list.append(girlsHtml);
Don't abuse this
$('#someAnchor').click(function() {
// Bleh
alert( $(this).attr('id') );
});
$('#someAnchor').click(function() {
alert( this.id );
});
//Add multiple events at the same time
$button.on({
"mouseenter": function() {
$(this).text("Click me!");
},
"click": function() {
$(this).text("Why did you click me?!");
}
});
BAD
GOOD
$body.on("mouseenter", function() {
$(this).text("Click me!");
});
$body.on("click", function() {
$(this).text("Why did you click me?!");
});
//Event delegation with parents, just once! :)
$list.on("click", "li.myitem", function(){
console.log("click");
});
//code code code
$list.append("<li class='myitem'>Demo</li>");
$list.append($("<li class='myitem'>Demo</li>")
.on.("click", function(){
console.log("click");
}));
//OR
$list.append("<li class='myitem'>Demo</li>");
$(".myitem").on.("click", function(){
console.log("click");
});
//Use json2 libray to support JSON.stringify in old browsers
$.ajax({
url: "http://.....",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json", //Request json in server side
dataType : 'json', //Response json in browser side
success : function(json) {
console.log(json);
alert("success");
},
error : function(xhr, status) {
alert('Error call service');
},
complete : function(xhr, status) {
alert('Finish');
}
});
var userId = 2;
$.getJSON("/api/users?id=" + userId , function(data, status){
alert("User Name: " + data.Name);
});
$.post( "http://myURL.com/usuario", {'nombre': 'Oscar'}, function( data, textStatus, jqxhr ) {
alert( "Exito" );
});
$(document).ajaxError(function() {
alert('Ajax Error');
});
Global
Link: http://nodeschool.io/
var gulp = require('gulp');
var gutil = require('gulp-util');
var concat = require('gulp-concat');
var sass = require('gulp-sass');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var paths = {
sass: ['./scss/**/*.scss'],
controllers: ['./www/js/controllers/*.js'],
directives: ['./www/js/directives/*.js'],
services: ['./www/js/services/*.js']
};
gulp.task('default', ['sass', 'controllers', 'directives', 'services']);
gulp.task('controllers', function() {
return gulp.src(paths.controllers)
.pipe(concat("controllers.js"))
.pipe(gulp.dest("./www/js/"))
.pipe(rename('controllers.min.js'))
.pipe(uglify())
.pipe(gulp.dest("./www/js/"));
});
gulp.task('watch', function() {
gulp.watch(paths.sass, ['sass']);
gulp.watch(paths.controllers, ['controllers']);
gulp.watch(paths.directives, ['directives']);
gulp.watch(paths.services, ['services']);
});
Example with Ionic Framework here
ECMAscript 6 is the next generation JavaScript standard, and the first update to the language since ES5 was standardized in 2009...
function f() {
{
let x;
{
// okay, block scoped name
const x = "sneaky";
// error, const
x = "foo";
}
// error, already declared in block
let x = "inner";
}
}
They support both expression and statement bodies
var evens = [1, 2, 3, 4, 5];
var nums = evens.map((v, i) => v + i);
console.log(nums); // [1,3,5,7,9]
var fives = [];
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
console.log(fives); // [5]
var nicholls = {
_name: "Nicholls",
_friends: ["Andrea", "Osman", "Silva"],
printFriends() {
var exit = [];
this._friends.forEach(f =>
exit.push(this._name + " knows " + f));
console.log(exit);
}
}
let x = [0,1,2];
x.map(x => console.log(x * x)); //arrow function
var x = [0,1,2];
x.map(function (x) { //anonymous function
console.log(x * x);
});
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
//call the parent constructor with super
super(geometry, materials);
//...
}
update(camera) {
//...
//call the parent method with super
super.update();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
are a simple sugar over the prototype-based OO pattern
// Superclass
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
describe() {
return 'Person called ' + this.name;
}
get getYears() {
return this.age;
}
set increaseAge() {
this.age++;
}
}
// Subclass
class Employee extends Person {
constructor(name, age, title) {
super(name, age);
this.title = title;
}
describe() {
return super.describe() + ' (' + this.title + ')';
}
}
function Car() {
var self = this; //locally assign this
self.speed = 0;
setInterval(function goFaster() {
//this has a different scope
self.speed += 5;
console.log('now going: ' + self.speed);
}, 1000);
}
var car = new Car();
function Car() {
this.speed = 0;
setInterval(() => {
this.speed += 5; //this is from Car
console.log
console.log('now going: ' + this.speed);
}, 1000);
}
//Create string
`In ES5 "\n" is a line-feed.` // "In ES5 \"\n\" is a line-feed.";
// Multiline strings
`In ES5 this is
not legal.`
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?` //Hello Bob, how are you today?
provide syntactic sugar for constructing strings
function renderPerson(person) { return `
<dl>
<dt>First</dt> <dd>${person.first}</dd>
<dt>Last</dt> <dd>${person.last}</dd>
</dl>
`;}
renderPerson({first: 'Brian', last: 'Genisio'});
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
console.log(f(3) == 15) // true
function f(x, ...y) {
// y is an Array
return x * y.length;
}
console.log(f(3, "hello", true) == 6)
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
console.log(f(...[1,2,3]) == 6); // true
// lib.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
// main.js
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
var p1 = new Promise((resolve, reject) => setTimeout(resolve, 400, "one"));
var p2 = new Promise((resolve, reject) => setTimeout(resolve, 200, "two"));
Promise.race([p1, p2]).then(function(value) {
console.log(value); //two
});
var p1 = new Promise((resolve, reject) => setTimeout(resolve, 400, "one"));
var p2 = new Promise((resolve, reject) => setTimeout(resolve, 200, "two"));
Promise.all([p1, p2]).then(function(value) {
console.log(value); //one, two
});
function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}
var p = timeout(1000).then(() => {
return timeout(2000);
}).then(() => {
throw new Error("hmm");
}).catch(err => {
return Promise.all([timeout(100), timeout(200)]);
})
Link: http://www.pluralsight.com/courses/javascript-design-patterns - Promises
Deferred object controls operation
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
Link: Javascript The Good Parts - Page 27
var myObject = {
value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment( );
document.writeln(myObject.value); // 1
myObject.increment(2);
document.writeln(myObject.value); // 3
When a function is stored as a property of an object, we call it a method...
A method can use this to access the object so that it can retrieve values from the object or modify the object
Link: Javascript The Good Parts - Page 28
// Augment myObject with a double method.
myObject.double = function ( ) {
var that = this; // Workaround.
var helper = function ( ) {
that.value = add(that.value, that.value);
};
helper( ); // Invoke helper as a function.
};
// Invoke double as a method.
myObject.double( );
document.writeln(myObject.getValue( )); // 6
When a function is not the property of an object, then it is invoked as a function...
Link: Javascript The Good Parts - Page 29
// Create a constructor function called Quo.
// It makes an object with a status property.
var Quo = function (string) {
this.status = string;
};
// Give all instances of Quo a public method
// called get_status.
Quo.prototype.get_status = function ( ) {
return this.status;
};
// Make an instance of Quo.
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status( )); // confused
Functions that are intended to be used with the new prefix are called constructors
Link: Javascript The Good Parts - Page 30
// Make an array of 2 numbers and add them.
var array = [3, 4];
var add = function(x, y){
return x + y;
};
var sum = add.apply(null, array); // sum is 7
// Make an object with a status member.
var statusObject = {
status: 'A-OK'
};
// statusObject does not inherit from Quo.prototype,
// but we can invoke the get_status method on
// statusObject even though statusObject does not have
// a get_status method.
var status = Quo.prototype.get_status.apply(statusObject);
// status is 'A-OK
The apply method lets us construct an array of arguments to use to invoke a function.
It also lets us choose the value of this.
The apply method takes two parameters.
The first is the value that should be bound to this. The second is an array of
parameters.
var awesomeNewModule = (function(){
var exports = {
foo: 5
};
exports.helloPeople = function(){
console.log("Hello guys!");
};
return exports;
}());
var awesomeNewModule.sub = (function(exports){
exports.foo = 5;
exports.helloPeople = function(){
console.log("Hello guys!");
};
return exports;
}(awesomeNewModule.sub || {}));
//File1.js
var awesomeNewModule = awesomeNewModule || {};
awesomeNewModule.sub = (function(exports){
exports.foo = 5;
exports.helloPeople = function(){
console.log("Hello guys!");
};
return exports;
})(awesomeNewModule.sub || {});
//File2.js
var awesomeNewModule = awesomeNewModule || {};
awesomeNewModule.sub = (function(exports){
exports.bla = 10;
exports.goodbyePeople = function(){
console.log("Bye bye guys!");
};
return exports;
})(awesomeNewModule.sub || {});
awesomeNewModule.sub.helloPeople();
awesomeNewModule.sub.goodbyePeople();
var App = App || {};
App.Models = (function(response){
response.User.prototype.jump = function(){
console.log(this.name + " is jumping!");
};
return response;
})(App.Models || {});
Extension of my library
var App = App || {};
App.Models = (function(response){
response.User = function(name){
this.name = name;
};
response.User.prototype.run = function(){
console.log(this.name + " is running!");
};
return response;
})(App.Models || {});
used for structuring desktop and server-side applications...
MVC is an architectural design pattern that encourages improved application organization through a separation of concerns.
JavaScript now has a number of frameworks boasting support for MVC (or variations on it, which we refer to as the MV* family), allowing developers to easily add structure to their applications without great effort.
Backbone, Ember.js and AngularJS
"spaghetti" code:
A term which describes code that is very difficult to read or maintain due to its lack of structure.
Manage the data for an application.
They represent unique forms of data that an application may require.
Represents a unique kind of domain-specific data. Such a model may contain related attributes
it is quite common for them to support validation of attributes
Views are a visual representation of models that present a filtered view of their current state.
A view typically observes a model and is notified when the model changes
The benefit of this architecture is that each component plays its own separate role in making the application function as needed.
Controllers are an intermediary between models and views which are classically responsible for updating the model when the user manipulates the view.
By J.D Nicholls
A course about JavaScript
Founding Full-Stack Web3 Engineer at @baxusco | Digital nomad 🎒 | Mentor 👨🏫 | Speaker 🗣️ | Developer 👨💻 | Creator of @proyecto26 #opensource #developer