strange JS

[] + {} //"[object Object]" {} + [] // 0

  • When an operand of the + operation is an object, the object is coerced into a primitive value. To achieve this coercion, first the valueOf() operation is invoked on the object. If it fails to produce a simple primitive, it falls back on the result of the toString() representation for the same.
  • If any operand of a + operation is a string, the resulting expression is also a string.

For [] + {}, the valueOf() operation on [] doesn’t produce a simple primitive and so the toString() method is invoked which results in [] being coerced into "". Since one operand of this + operation is a string, the other operand, {} is also coerced to a string, producing "[object Object]".

For {} + [] , however, {} is interpreted as a stand-alone empty block (semicolons aren’t needed to terminate them) and + [] as an expression which results in the explicit coercion of [] to a number value, 0. It might as well be represented as : {}; +[] .

Booleans don’t play nice when compared with other primitives; they give unexpected results

boolean JS comparison

    Solutions:

  • For the first example, the type of x is indeed Boolean, so it performs ToNumber(x), which coerces true to 1. Now, 1 == “42” is evaluated. The types are still different, so (essentially recursively) we re-consult the algorithm, which just as above will coerce “42” to 42, and 1 == 42 is clearly false.
  • Similarly, in the second example, x is coerced to 1 while y is passed to the ToNumber() algorithm where ‘true’ is coerced to NaN and since 1 == NaN, also, is quite clearly false, we get the aforementioned result.

object comparison

We often need to check if two object references point to the same object and employ the == operator to achieve that effect

object comparison js object comparison js 2

pre-increment with post-increment

Pre-increment with post-increment

'name' must be named with caution

'name' must be named with caution

name or window.name is a reserved keyword. When name is set to any value, it is automatically stringified, i.e, the toString() method is called on it . window.name gets/sets the name of the window. This only happens for var declarations and not for let declarations since let variables do not attach themselves to the window object.

undefined and null, same but different

undefined and null coerce to each other when compared with ==

undefined and NaN

caveat to destructuring

caveat for destructuring

A monolithic architecture means that your app is written as one cohesive unit of code whose components are designed to work together, sharing the same memory space and resources.

A microservice architecture means that your app is made up of lots of smaller, independent applications capable of running in their own memory space and scaling independently from each other across potentially many separate machines.

    Monolithic Pros:

  • The major advantage of the monolithic architecture is that most apps typically have a large number of cross-cutting concerns, such as logging, rate limiting, and security features such audit trails and DOS protection. When everything is running through the same app, it’s easy to hook up components to those cross-cutting concerns.
  • There can also be performance advantages, since shared-memory access is faster than inter-process communication (IPC).

    Monolithic Cons:

  • Monolithic app services tend to get tightly coupled and entangled as the application evolves, making it difficult to isolate services for purposes such as independent scaling or code maintainability.
  • Monolithic architectures are also much harder to understand, because there may be dependencies, side-effects, and magic which are not obvious when you’re looking at a particular service or controller.

    Microservice Pros:

  • Microservice architectures are typically better organized, since each microservice has a very specific job, and is not concerned with the jobs of other components.
  • Decoupled services are also easier to recompose and reconfigure to serve the purposes of different apps (for example, serving both the web clients and public API).
  • They can also have performance advantages depending on how they’re organized because it’s possible to isolate hot services and scale them independent of the rest of the app.

    Microservice Cons:

  • As you’re building a new microservice architecture, you’re likely to discover lots of cross-cutting concerns that you did not anticipate at design time. A monolithic app could establish shared magic helpers or middleware to handle such cross-cutting concerns without much effort.
  • In a microservice architecture, you’ll either need to incur the overhead of separate modules for each cross-cutting concern, or encapsulate cross-cutting concerns in another service layer that all traffic gets routed through.
  • Eventually, even monolthic architectures tend to route traffic through an outer service layer for cross-cutting concerns, but with a monolithic architecture, it’s possible to delay the cost of that work until the project is much more mature.
  • Microservices are frequently deployed on their own virtual machines or containers, causing a proliferation of VM wrangling work. These tasks are frequently automated with container fleet management tools.

Positive attitudes toward microservices, despite the higher initial cost vs monolthic apps. Aware that microservices tend to perform and scale better in the long run.

Structure the app so that services are independent from each other at the code level, but easy to bundle together as a monolithic app in the beginning. Microservice overhead costs can be delayed until it becomes more practical to pay the price.