Writing quality JavaScript is hard...
You have to know what to do...
Namespace your functions...
var AwesomeNS = {};
AwesomeNS.rockstar = function () {
// Good job, rockstar!
}
Decalre your vars up top...
AwesomeNS.rockstar = function () {
var thisIsHow = "we do it";
// No block scope, here!
}
Encapsulate your code in IIFEs
(function () {
var giveAHoot = !pollute;
// ...the global namespace!
}());
And what not to do...
Don't use with...
bad = "hehe";
with (theNS) {
// is this theNS.bad or bad.
// Who knows!
bad = "oh noes";
}
Always remember your vars...
function derp() {
for (i = 0; i < 10; i++) {
// You just modified
// the global 'i'!
}
}
Stop abusing eval...
var property = 'bar';
var value = eval('foo.' + property);
value = foo[property]; // Good!
But you know all that.
Because you are a rockstar!
Come on...
None of us are perfect.
We all write bad code.
Especially JavaScript.
So we write tests.
Tests in JavaScript.
And we run them in our CI server.
Now front-end engineers can
break the build.
And that is a very good thing.
Live Coding Time!!!
(I am such a fool...)
Jasmine
NS.greeter = function (name) {
return 'Hello ' + name + '!';
};
describe('greeter', function () {
it('greets me', function () {
expect(NS.greeter('Trevor')).toEqual('Hello Trevor!');
});
});
Jasmine with Callbacks
NS.runIfTrevor = function (name, callback) {
if (name === 'Trevor') {
callback(name);
} else {
console.log("You aren't Trevor!");
}
};
describe('runIfTrevor', function () {
it('calls callback if Trevor', function () {
var callback = jasmine.createSpy();
NS.runIfTrevor('Trevor', callback);
expect(callback).toHaveBeenCalledWith('Trevor');
});
});
Jasmine with Ajax
NS.greetUser = function (id) {
return $.ajax({
data: id,
url: 'name.html',
success: function (data) {
NS.greeter(data.name);
}
});
};
describe('greetUser', function () {
it('calls greeter on success', function () {
NS.greetUser(1);
spyOn(NS, 'greeter');
mostRecentAjaxRequest().response({
status: 200,
responseText: '{"name":"Trevor"}'
});
expect(NS.greeter).toHaveBeenCalledWith('Trevor');
});
});