The basic philosophy of node.js is:
- Non-blocking I/O.
- every I/O call must take a callback, whether it is to retrieve information from disk, network or another process.
- Built-in support for the most important protocols (HTTP, DNS, TLS).
- Low-level. Do not remove functionality present at the POSIX layer. For example, support half-closed TCP connections.
- Stream everything; never force the buffering of data.
this keyword is not fixed to a particular value. Instead, the value of this is determined by how the function is called:
|Execution Context||Syntax of function call||Value of this|
|Global||n/a||global object (e.g. window)|
|Function||Method call: myObject.foo();||myObject|
|Function||Baseless function call: foo();||global object (e.g. window) (undefined in strict mode)|
|Function||Using call: foo.call(context, myArg);||context|
|Functions||Using apply: foo.apply(context, [myArgs]);||context|
|Function||Constructor with new: var newFoo = new Foo();||the new instance (e.g. newFoo)|
|Evaluation||n/a||value of this in parent context|
Calls the function, setting the value of this to thisArg and the arguments of the function the values of argsArray.
Function.call(thisArg[, arg1[, arg2[, ...]]])
Calls the function, setting the value of this to thisArg, and passing the arguments arg1, arg2 ... to the function.
apply() allow us to specify what the value of this should be. The difference between the two is how they pass on additional arguments.
Call() takes the actual arguments of
apply() takes just two arguments: thisArg and an array of arguments.
Adding properties in a particular order to an object does not guarantee that the properties will be iterated in that order.
Object prototypes should only define methods, not data.
Don't construct by return objects (even though was introduced in The Good Parts), use prototype and new.