By Julien Muetton / @themouette
OpenStudio 2013 December, 5th
When altering a node, DOM is rendered again.
To avoid performances issues, you need to work on a detached piece of DOM.
A Fragment is an empty DOM node.
automatic semicolon insertion force to put braces at the EOL
// BAD
return
{
foo: "foo"
};
vs
// GOOD
return {
foo: "foo"
};
Use `Array.join()` to declare multiline strings
// BAD
var foo = 'Lorem ipsum dolor sit amet, consetetur '
+ 'sadipscing elitr, sed diam nonumy ';
vs
// GOOD
var foo = [
'Lorem ipsum dolor sit amet, consetetur ',
'sadipscing elitr, sed diam nonumy '
].join('');
Lambda functions are shown as (anonymous) in debugger.
// BAD
var foo = function() {
/* ... */
};
vs
// GOOD
var foo = function foo() {
/* ... */
};
Variable initialization should remain readable
// BAD
var foo = new Object();
foo.name = 'John';
foo.age = 32;
vs
// GOOD
var foo = {
name: 'john',
age: 32
};
Semicolons `;` are optional as
a = b + c
foo()
// All right
a = b + c ; foo()
a = b + c
[1].push(a)
// Not what expected
a = b + c[1].push(a)
a = b + c
(opts || {}).foo ? bar() : baz()
// Not what expected
a = b + c(opts || {}).foo ? bar() : baz()
Either you learn
ASI rules or you write semicolons
To go further on
More advices in the Airbnb JavaScript Style Guide
var foo = "outside";
function test() {
var foo = "inside";
console.log('test foo is "%s"', foo);
}
test();
console.log('outside foo is "%s"', foo);
Will output
test foo is "inside"
outside foo is "outside"
Each function defines its own context and can access definition context.
Any variable not declared with var
is global.
var foo = "outside";
function test() {
foo = "inside";
console.log('test foo is "%s"', foo);
}
test();
console.log('outside foo is "%s"', foo);
Will output
test foo is "inside"
outside foo is "inside"
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
// Is compiled into
var foo = 1;
function bar() {
var foo;
if (!foo) {
foo = 10;
}
alert(foo);
}
bar();
Variable declarations are hoisted to the top of context by compiler
var a = 1;
function b() {
a = 10;
return;
function a() {};
}
b();
alert(a);
// Is compiled into
var a = 1;
function b() {
// declare a symbol locally
function a() {};
a = 10;
return;
}
b();
alert(a);
Function declarations are hoisted too.
To go further on hoisting: adequatelygood
A closure is a function alongside a referencing environment.
To be short, you can reference variables that belongs to the context where function was defined.
In the meantime, a function creates its own context.
var x = 0;
function incr() {
x++;
console.log(x);
}
function decr() {
x--;
console.log(x);
}
console.log(x); // log 0
incr(); // log 1
incr(); // log 2
decr(); // log 1
Create a callback from a variable:
function createAdd(number) {
function doAdd(value) {
return value + number;
}
return doAdd;
}
var add10 = createAdd(10);
alert(add10(1)); // returns 11
Closure creates it's own context:
var x = 5;
function foo() {
var x = 12;
function myFun() {
// do something
}
return myFun;
}
console.log(foo()); // log function myFun() {...}
console.log(x); // log 5
console.log(myFun); // reference error
this
keywordvar john = {
name: "John"
};
john.sayHello = function () {
alert("Hello " + this.name);
};
john.sayHello();
this
is the object.
var name = "Garry";
function sayHello() {
alert("Hello " + this.name);
}
sayHello();
this
is the current context:
var name = "Garry";
var joe = {
name: "Joe"
};
joe.sayHello = function sayHello() {
alert("Hello " + this.name);
}
var fct = joe.sayHello;
fct();
var joe = {
name: "Joe"
};
function sayHello(greeting, to) {
greeting || (greeting = 'Hello');
to || (to = 'annonymous');
alert([greeting, to, 'I\'m', this.name].join(' '));
}
sayHello.call(joe, 'Good morning', 'Garry');
sayHello.apply(joe, ['Good morning', 'Garry']);
will both result into
Good morning Garry, I'm Joe.
function bind(context, method) {
return function () {
method.apply(context, arguments);
}
}
This way, you can make sure the context is what you expect.
In jQuery it is called $.proxy
.
Read more on partial application on Cowboy's blog and Invocation patterns in depth