$('#id').click(function() {
alert('something!');
});
$.getJSON('http://somewhere', function(data) {
alert(data);
});
var a = [1, 2, 3, 4, 5];
var result = _.reject(a, function(item) { return item > 3; });
console.log(result);
var b = [3, 4, 5, 6, 7];
var result = _.intersection(a, b);
console.log(result);
runuse todomvc to shop around
why wouldn't you? organize your code intelligently!
XCode/VS/Eclipse | open source |
---|---|
big IDE | text editors |
large built-in set of libaries | many options with separate communities |
official channels | usually github |
intellisense, docs, blogs | annotated source, blogs, sometimes docs |
which brings us to...
how do you manage lots of libraries?
jquery "1.x" or jquery "~1.10.2"
npm allows you to be hardcore: shrinkwrap
mocha.setup('bdd');
describe('MyClass', function() {
before(function(done) {
// initial setup, async because arity > 0
done();
});
beforeEach(function() {
// before every test
});
describe('#method', function() { // nested describe
it('should handle a null parameter', function() {
// test logic here, exceptions denote failure
});
});
});
runruns in the browser and on the command line
var expect = chai.expect;
var x;
expect(x).not.to.exist;
var data = { x: 6 };
expect(data).to.have.property('x', 6);
expect(data).to.deep.equal({x: 6});
runvar spy = sinon.spy(String.prototype, 'toUpperCase');
expect(spy).to.have.property('callCount', 0);
expect('blah'.toUpperCase()).to.equal('BLAH');
expect(spy).to.have.property('callCount', 1);
spy.restore();
var stub = sinon.stub().returns(6);
expect(stub()).to.equal(6);
expect(stub).to.have.property('callCount', 1);
runit can also redirect $.ajax and sandbox entire browser
no instrumentation step!
easy client-side setup
<script src="blanket.js"></script>
<script src="my-library.js" data-cover></script>
easy node.js setup
mocha --require blanket --reporter html-cov testfile1.js testfile2.js
// in package.json:
"scripts": {
"blanket": {
"data-cover-only": "src"
}
}
comments interspersed with source
meaningful tags
use only for production; breaks mocha testing
var _ = require('lodash');
module.exports = function(options) {};
define(['lodash'], function(_) {
return function(options) {};
});
pro: no build step required; detailed control
con: boilerplate required for every file
pro: stubs out standard node.js components for you
con: requires build step to get into browser
pro: can prune unused code
con: requires build step to get into browser
function Obj(options) {
options = options || {};
this.Database = options.Database || Database;
this.database = new this.Database();
this.service = options.service || service;
}
Not a common thing in javascript world yet.
Angular - the first mainstream project to take it seriously.
other folks are experimenting with it
console.log(!!null);
console.log(!!undefined);
console.log(!!false);
console.log(!!0);
console.log(!!'');
console.log(!!NaN);
var f = function() {};
console.log(!!f);
console.log(!!1);
console.log(!!'something');
console.log(!!true);
runvar o = {a: 0};
console.log(o.a == '0');
console.log(o.a == 0);
console.log(o.a === '0');
console.log(o.a === 0);
o.a = null;
console.log(o.a == null);
delete o.a; // now it's undefined
console.log(o.a == null);
runvar f = function(a) {
console.log(arguments);
}
console.log(typeof f);
console.log(f);
console.log(f.length);
f.a = 4;
console.log(f.a);
f(6, 7);
f.call(null, 6, 7);
f.apply(null, [6, 7]);
runvar a = 1;
var f = function(b) {
return function(c) {
console.log('a: ' + a + '; b: ' + b + '; c: ' + c);
}
}
var g = f('2');
g(3);
g(4);
a = 2;
g(5);
runx = 0;
var first = setInterval(function() {
x += 1;
console.log(x);
}, 1);
var second = setInterval(function() {
x -= 1;
console.log(x);
}, 1);
setTimeout(function() {
clearInterval(first);
clearInterval(second);
}, 250);
run(web workers do now allow concurrency, but you don't have access to the same context)
function Super(options) { this.a = options.a };
Super.prototype.f = function() { console.log(this.a); };
function Sub(options) {
Super.call(this, options);
};
Sub.prototype = Object.create(Super.prototype, {
constructor: { value: Sub }
});
var p = new Super({a: 'super'});
p.f();
var c = new Sub({a: 'sub'});
c.f();
Sub.prototype.g = function() { console.log('post create add!'); };
c.g();
runfunction Obj() { this.value = 1; };
Object.defineProperty(Obj.prototype, 'property', {
get: function() {
return 'computed: ' + this.value;
},
set: function(value) {
this.value = value;
}
});
var o = new Obj();
console.log(o.property);
o.property = 2;
console.log(o.value);
runObject.create and Object.defineProperty are ES5 features.
which brings us to...
support matrix for javascript features, css, svg, html5
detailed es5 feature matrix
overall javascript feature support
polyfill: downloadable code providing functionality not built into a web browser
function Obj() { this.x = 7; };
Obj.prototype.f = function() { console.log(this); };
var o = new Obj();
o.f();
var g = o.f; // pull the method out
g(); // raw call, gets global context
g.call(o);
g = _.bind(g, o);
g();
var nope = Obj(); // forgot the new
console.log(nope); // undefined!
console.log(x); // where did this come from?
runwhich brings us to...
fixing some of the key problems with javascript
'use strict';
// these no longer parse
var broken = function(dupe, dupe) {}; // no duplicate parameters
var broken = { dupe: 1, dupe: 2 }; // no duplicate keys
with ({}) { x = 4; y = 3; } // no more with
var x = 015; // you probably don't mean octal syntax
// these fail at runtime
function Obj() { this.x = 7; };
var nope = Obj(); // this not set to global anymore
y = 5; // using undefined var
delete Object.prototype; // this would normally fail silently
runyou'll need to be a careful, since it changes behavior
perhaps you'd like to check the maintainability of your code?
(best implemented using a grunt task)
which brings us to...
tasks available for jshint, mocha, watch, concat/minify, etc.
powerful api for developing your own tasks
fortunately, there are tools to help you jump in really fast
[sudo] npm install -g yo generator-webapp
mkdir yeoman-app
cd yeoman-app
yo webapp
study it for best practices, improve it, fork it, pull request it!