To track download progress, we can use response.body property.… We gather response chunks in the array chunks.… At the end, we have chunks – an array of Uint8Array byte chunks.… We need to join them into a single result.… Then we can JSON.parse it, if necessary.
What if we need binary content instead of a string?
However, when we pass these to a function, we may not need all of it.… have a complex object with many properties, we can extract only what we need:… We can use the rest pattern, just like we did with arrays.… We want destructuring instead.… If we want all values by default, then we should specify an empty object:
to each of them – we put a single handler on their common ancestor.… In our case if we take a look inside the HTML, we can see nested tags inside <td>, like <strong… And we can use it in CSS rules too.… There can be as many attributes with data-counter as we want.… We can add new ones to HTML at any moment.
Please note that we actually don’t use this here.… For instance, we have a function send(from, to, text).… We can’t just omit the context and jump to arguments.… Usually we apply bind to fix this for an object method, so that we can pass it somewhere.… Like if we have a send(from, to) function, and from should always be the same for our task, we can get
In theory, we could create any invisible element somewhere in HTML for HTML markup storage purposes.… That’s not what we want. On the other hand, <template> keeps exactly what we place there.… The content becomes live (styles apply, scripts run etc) when we insert it into the document.… We can treat it as any other DOM node, except one special property: when we insert it somewhere, its… We can access template.content from JavaScript, clone it to reuse in a new component.
Escaping.Let’s say we want to find literally a dot. Not “any character”, but just a dot.… want them, we should use \(.… a special character, but in JavaScript it is used to open and close the regexp: /...pattern.../, so we… * + ( ) literally, we need to prepend them with a backslash \ (“escape them”).… We also need to escape / if we’re inside /.../ (but not inside new RegExp).
Hopefully it’s obvious enough, but we still have to mention it.… We should always prefer CSS classes to style.… Sometimes that’s what we need, but often we want to add/remove a single class.… What we choose depends on our needs.… But we can safely use it for new elements, when we know we won’t delete an existing style.
run the code, we can notice something strange.… So we should listen on document to catch it.… So we hide it and immediately show again.… We can lay a lot on this foundation.… We can limit dragging by a certain area or direction.
We can use event delegation for mousedown/up.
So, when we have published a new version of our app, and the user visits our webpage, we may need to… Or we can auto-generate keys.
But we need to create an object store first.… , and we fail to do the 2nd.… The short answer is: we don’t.… In our example, we store books keyed by id.
Let’s say we want to search by price.
Let’s say we have a string like +7(903)-123-45-67 and want to find all numbers in it.… To mark how many we need, we can append a quantifier.… To make a regexp more precise, we often need make it more complex
We can see one common rule… For instance, for HTML tags we could use a simpler regexp: <\w+>.… Can we use <\w+> or we need <[a-z][a-z0-9]*>?
And it still works, we can find it in the old code.… We can’t capture them partially, like we did with rest parameters.… But sometimes we need to do exactly the reverse.… How do we call Math.max with it?… prefer to use it whenever we can.
We already know how to work with them.… Now we want to add a fullName property, that should be "John Smith".… Of course, we don’t want to copy-paste existing information, so we can implement it as an accessor:… We don’t call user.fullName as a function, we read it normally: the getter runs behind the scenes.… For instance, if we want to forbid too short names for user, we can have a setter name and keep the value
As we know, fetch returns a promise.… So how can we cancel an ongoing fetch?… Generally, we have two parties in the process:
The one that performs a cancelable operation, it sets… We can use AbortController in our code.… We can use it even without fetch.
Export and import statements that we covered in previous chapters are called “static”.… First, we can’t dynamically generate any parameters of import.… This won’t work:
Second, we can’t import… But how can we import a module dynamically, on-demand?… So we can’t copy import to a variable or use call/apply with it. It’s not a function.
may get this error if we forget to put async before a function.… async/await and promise.then/catch
When we use async/await, we rarely need .then, because… And we can use a regular try..catch instead of .catch.… async/await works well with Promise.all
When we need to wait for multiple promises, we can… With async/await we rarely need to write promise.then/catch, but we still shouldn’t forget that they
If we really want to show a symbol, we need to explicitly call .toString() on it, like here:… The idea is that when we clone an object or merge objects, we usually want all properties to be copied… If we want same-named symbols to be equal, then we should use the global registry: Symbol.for(key) returns… If we want to add a property into an object that “belongs” to another script or a library, we can create… So we can “covertly” hide something into objects that we need, but others should not see, using symbolic
Blob objects are immutable
We can’t change data directly in a Blob, but we can slice parts… This behavior is similar to JavaScript strings: we can’t change a character in a string, but we can make… In the last example, we intend the Blob to be used only once, for instant downloading, so we call URL.revokeObjectURL… But if we need to perform low-level processing, we can get the lowest-level ArrayBuffer from blob.arrayBuffer… We can easily convert between Blob and low-level binary data types:
We can make a Blob from a typed
That’s easy to understand if we look a bit under the hood of what happens when we copy a value.… As a result we have two independent variables, each one storing the string "Hello!… Then, if we later use another key (user), we are still opening the same cabinet and can access the changed… But what if we need to duplicate an object?… Nested cloning.Until now we assumed that all properties of user are primitive.
If we handle an event in JavaScript, we may not want the corresponding browser action to happen, and… So we use <a> in the markup. But normally we intend to handle clicks in JavaScript.… So we should prevent the default browser action.… If we prevent the mousedown event, there’s no focus.… The problem is that when we click on elem, we get two menus: the button-level and (the event bubbles
As we know, objects can store properties.… We didn’t see them yet, because generally they do not show up.… When we create a property “the usual way”, all of them are true.… don’t like it, then we can set enumerable:false.… We cannot change it back with defineProperty.
So technically we don’t have to use URL. But sometimes it can be really helpful.… We can pass URL objects to networking (and most other) methods instead of a string
We can… If we use a string though, we need to encode/decode special characters manually.… When we should use either?”… But we should encode & inside a search parameter, otherwise, we get q=Rock&Roll – that is actually
E.g. we have a code string let varName = "value", and we need to read the variable name from… We can add the flag g.… Again, not what we need.
So, how to search for a regexp exactly at the given position?… We can manually set lastIndex to 4, to start the search from the given position!… Imagine, we have a long text, and there are no matches in it, at all.
How do we find the width and height of the browser window?… How do we scroll the page using JavaScript?… They look like what we want, so why not to use them instead?… In modern HTML we should always write DOCTYPE.… we want the visitor to interact with that message, not with the document.
We can use its features via the external interface.… A coffee machine has a lot of details, we won’t model them to stay simple (though we could).… For instance, we don’t want anyone to set it below zero.… If we extend a CoffeeMachine, we may have legitimate reasons to access its internals.… As we know, usually we can access fields using this[name]:
But how do we know about that in JavaScript?… Power of n.If we want to speed up the animation, we can use progress in the power n.… First we “pull the bowstring”, and then “shoot”.… All we need is to write the proper draw.… Unlike CSS, we are not limited to Bezier curves here.
Why do we need tests?.… When we write a function, we can usually imagine what it should do: which parameters give which results… We fix the code and now f(2) works. Looks complete? But we forgot to re-test f(1).… When we develop something, we keep a lot of possible use cases in mind.… We assume that n≥0.
So, if we want all results to be shown by for..of, we must return them with yield:… , but we can also make a generator that yields values forever.… To do so, we should call generator.next(arg), with an argument.… Often we don’t use it, as most of time we want to get all returning values, but it can be useful when… we want to stop generator in a specific condition.
In other words, we want to add an iteration ability to the object.… Here we just delay for a second (3).… In regular generators we can’t use await.… It has a special format, so we use a regular expression for that (we will learn this feature in Regular… We can use async generators to process such data.
When we develop something, we often need our own error classes to reflect specific things that may go… If the readUser function generates several kinds of errors, then we should ask ourselves: do we really… The technique that we describe here is called “wrapping exceptions”.… We can inherit from Error and other built-in error classes normally.… We just need to take care of the name property and don’t forget to call super.
How can we make code finished appear after promise done?… Normally, if we expect an error, we add .catch to the promise chain to handle it:… If we didn’t know about the microtasks queue, we could wonder: “Why did unhandledrejection handler run… We did catch and handle the error!”… If we need to guarantee that a piece of code is executed after .then/catch/finally, we can add it into
In other words, actions that we initiate now, but they finish later.… Let’s say we need to use the new script as soon as it loads.… It declares new functions, and we want to run them.… Now if we want to call new functions from the script, we should write that in the callback:… load 1.js, then if there’s no error…
We load 2.js, then if there’s no error…
We load 3.js, then if there
So we can work with it like with other kinds of values.… We can pass it between variables and run when we want.… We can think of it as an “initialization stage”.… that we get during runtime.… And then we plan to use it some time later.
And then we can use it everywhere.… So we can’t really render there.… Usually, when we change an attribute, like a.href, we expect the change to be immediately visible.… At the end, we can easily make a live timer.… Or, if we really need the children, we can defer access to them with zero-delay setTimeout.
But we cannot read location (so we can’t see where the user is now, no information leak).… If we set any event handlers on it, they will be ignored.… can put a space-delimited list of those that we want to lift.… In other words, if we want to send the message to win, we should call win.postMessage(data, targetOrigin… We can immediately source.postMessage(...) back if we want.
We can imagine an object as a cabinet with signed files.… And if we need something more complex, then we switch to square brackets.… In other words, if we loop over an object, do we get all properties in the same order they were added… Can we rely on this?… But if we run the code, we see a totally different picture:
USA (1) goes first
then Switzerland (41)
In programming, we often want to take something and extend it.… JavaScript will throw an error if we try to assign __proto__ in a circle.… So when we write data into this, it is stored into these objects.… We did not define it.… We can use obj.
With new we all know that the new object is being created.… Of course, we can add to this not only properties, but methods as well.… We can use constructor functions to make multiple similar objects.… In this chapter we only cover the basics about objects and constructors.… After we learn that, we return to objects and cover them in-depth in the chapters Prototypes, inheritance
We need to wait until the script loads, and only then we can call it.… We don’t know if it was an error 404 or 500 or something else.… Why do we need error details?… That’s great, as we can see real errors, triggered by our users.… We have the full error report.
We can use the contents of capturing groups (...) not only in the result or in the replacement string… We need to find quoted strings: either single-quoted '...' or a double-quoted "...… We can put both kinds of quotes in the square brackets: ['"](.*?)… Please note:
If we use ?: in the group, then we can’t reference it.… To reference a named group we can use \k<name>.
That’s great, because we can have many functions that could use such a feature, and all we need to do… We can apply it to another function.… We would observe a similar symptom if we tried to run:… Also we need to pass not just x, but all arguments in func.call.… We can add one or add many. And all this without changing its code!
In the previous chapter we saw methods map.keys(), map.values(), map.entries().… If we ever create a data structure of our own, we should implement them too.… So we may have an object of our own like data that implements its own data.values() method.… And we still can call Object.values(data) on it.… We can make powerful chains of transforms this way.
We can alter them.… So here we have "123" as the value.… We should refer to attributes only when DOM properties do not suit us, when we need exactly attributes… , for instance:
We need a non-standard attribute.… We want to read the value “as written” in HTML.
We can not only assign handlers, but also generate events from JavaScript.… We can generate not only completely new events, that we invent for our own purposes, but also built-in… we want to pass with the event.… Technically we could live without, because we can assign any properties into a regular new Event object… Let’s say we don’t like it.
But quite often we find that we need an ordered collection, where we have a 1st, a 2nd, a 3rd element… In practice we need it very often.… We can add any properties to them.… But still we should be aware of the difference.
Generally, we shouldn’t use for..in for arrays.… Getting the elements:
we can get element by its index, like arr[0]
also we can use at(i) method that
Otherwise, we can represent pow(x, n) as x * pow(x, n - 1).… Imagine, we have a company.… Now let’s say we want a function to get the sum of all salaries. How can we do that?… Alternatively, if we really need fast insertion/deletion, we can choose another data structure called… …But we don’t always need such operations.
To get them, we should search using the method str.matchAll(regexp).… We can turn it into a real Array using Array.from.… To look for all dates, we can add flag g.… :.Sometimes we need parentheses to correctly apply a quantifier, but we don’t want their contents in… item, we can write: (?
So we can’t see it.… We could make a function and put the code there.… We can append other nodes to it, but when we insert it somewhere, then its content is inserted instead… But usually the returned value is not used, we just run the method.… If we call it afterwards, the existing document content is erased.
No matter how great we are at programming, sometimes our scripts have errors.… Should we be satisfied with that? Of course not!… We can use them to create error objects as well.… If we don’t know how to handle it, we do throw err.… We apply it when we don’t want to handle errors here (let them fall through), but want to be sure that
But when we sort things out, everything becomes fairly simple.… We used that syntax already.… We can iterate, map, slice, find, reduce etc.… There are few things we can’t do though:
No splice – we can’t “delete” a value, because typed arrays… All we can do is to assign a zero.
No concat method.
When exactly should we run that highlighting method?… We find code snippets in HTML and highlight them.
Now let’s go on.… We need to call Prism.highlightElem on them, otherwise they won’t get highlighted.… …But, imagine if we have many places in the code where we load our content… We can add/remove code snippets in HTML without thinking about it.
Only first 50 results are shown.