Where is Blob binary data stored?

All variables that are not explicitly represented in any other storage are stored in memory (RAM) and lives there till end of your program or while you unset it (clear it from memory).

TLDR; In RAM


This will not answer your question fully.

So what happens when a new Blob() is declared?

From official fileAPI documentation,

The Blob() constructor can be invoked with zero or more parameters. When the Blob() constructor is invoked, user agents must run the following Blob constructor steps:
[1] If invoked with zero parameters, return a new Blob object with its readability state set to OPENED, consisting of 0 bytes, with size set to 0, and with type set to the empty string.
[2] Otherwise, the constructor is invoked with a blobParts sequence. Let a be that sequence.
[3] Let bytes be an empty sequence of bytes.
[4] Let length be `a`s length. For 0 ≤ i < length, repeat the following steps:
    1. Let element be the ith element of a.
    2. If element is a DOMString, run the following substeps:
        Let s be the result of converting element to a sequence of Unicode characters [Unicode] using the algorithm for doing so in WebIDL.
        Encode s as UTF-8 and append the resulting bytes to bytes.
    Note:
        The algorithm from WebIDL [WebIDL] replaces unmatched surrogates in an invalid UTF-16 string with U+FFFD replacement characters. Scenarios exist when the Blob constructor may result in some data loss due to lost or scrambled character sequences.  

    3. If element is an ArrayBufferView [TypedArrays], convert it to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView [TypedArrays], and append those bytes to bytes.
    4. If element is an ArrayBuffer [TypedArrays], convert it to a sequence of byteLength bytes, and append those bytes to bytes.
    5. If element is a Blob, append the bytes it represents to bytes. The type of the Blob array element is ignored.  
[5] If the type member of the optional options argument is provided and is not the empty string, run the following sub-steps:
    1. Let t be the type dictionary member. If t contains any characters outside the range U+0020 to U+007E, then set t to the empty string and return from these substeps.
    2. Convert every character in t to lowercase using the "converting a string to ASCII lowercase" algorithm.
[6] Return a Blob object with its readability state set to OPENED, referring to bytes as its associated byte sequence, with its size set to the length of bytes, and its type set to the value of t from the substeps above. 

A Blob is stored in the memory much like any other ArrayBuffer. It's stored in the ram, just like the other objects declared in the window.

Looking at the chrome://blob-internals, we can see how its physically stored in the ram. Here is an example blob.

c7828dad-dd4f-44e6-b374-9239dbe35e35
    Refcount: 1
    Status: BlobStatus::DONE: Blob built with no errors.
    Content Type: application/javascript
    Type: file
    Path: /Users/Chetan/Library/Application Support/Google/Chrome/Default/blob_storage/c7828dad-dd4f-44e6-b374-9239dbe35e35/0
    Modification Time: Monday, June 5, 2017 at 4:29:53 PM
    Offset: 4,917,846
    Length: 224,733

On printing the actual contents of the blob, we get a normal js file.

$ cat c7828dad-dd4f-44e6-b374-9239dbe35e35/0

...
html {
   font-family: sans-serif;
   /* 1 */
   -ms-text-size-adjust: 100%;
   /* 2 */
   -webkit-text-size-adjust: 100%;
   /* 2 */ }

/**
 * Remove default margin.
 */
body {
    margin: 0; }
...

Blobs represent a bunch of data that could live anywhere. The File API specification intentionally does not offer any synchronous way of reading a Blob's contents.

Here are some concrete possibilities.

  1. When you create a Blob via the constructor and pass it in-memory data, like an Uint8Array, the Blob's contents lives in memory, at least for a while.
  2. When you get a Blob from <input type="file">, the Blob's contents lives on disk, in the file selected by the user. The spec mentions snapshotting, but no implementation does it, because it'd add a lot of lag to user operations.
  3. When you get a Blob from another client-side storage API like IndexedDB or the Cache Storage API, the Blob's contents lives in the API's backing store on disk.
  4. Some APIs may return a Blob whose data streams from the network. The XMLHttpRequest spec makes this impossible, and I think the fetch spec also requires retrieving the entire response before creating the Blob. However, there could be a future spec that streams an HTTP response.
  5. Blobs created via the Blob constructor via an array of pieces may have their contents scattered across all the places mentioned above.

In Chrome, we use a multi-process architecture where the browser process has a central registry of all live Blobs, and serves as the source of truth for blob contents. When a Blob is created in a renderer (by JavaScript), its contents is moved to the browser process via IPC, shared memory, or temporary files, depending on the size of the Blob. The browser process may also evict in-memory Blob contents to temporary files. The 500mb limit mentioned in a previous answer was lifted around 2016. More implementation details are in the README for Chrome's Blobs subsystem.