tags : #area/watch #dev #javascript
source : eloquent Javascript 3rd
date : 2023-06-26
tags : #resources
source : https://stackoverflow.com/questions/2856059/passing-an-array-as-a-function-parameter-in-javascript
date : 2023-01-11
half of 100 is ${100 / 2}
When you write something inside ${} in a template literal, its result will be computed, converted to a string, and included at that position. The example produces “half of 100 is 50”.
There are two special values, written null and undefined, that are used to denote the absence of a meaningful value. They are themselves values, but they carry no information.
Many operations in the language that don’t produce a meaningful value (you’ll see some later) yield undefined simply because they have to yield some value.
The difference in meaning between undefined and null is an accident of JavaScript’s design, and it doesn’t matter most of the time. In cases where you actually have to concern yourself with these values, I recommend treating them as mostly interchangeable.
When an operator is applied to the “wrong” type of value, JavaScript will
quietly convert that value to the type it needs, using a set of rules that often
aren’t what you want or expect. This is called type coercion
When you do not want any type conversions to happen, there are two additional operators: = and !
. The first tests whether a value is precisely equal to the other, and the second tests whether it
is not precisely equal. So "" === false is false as expected. I recommend using the three-character comparison operators defensively to
prevent unexpected type conversions from tripping you up.
The || operator, for example, will return the value to its left when that can be converted to true and will return the value on its right otherwise. This has the expected effect when the values are Boolean and does something analogous for values of other types.
console.log(null || "user")
// → user
console.log("Agnes" || "user")
// → Agnes
have a value that might be empty, you can put || after it with a replacement
value. If the initial value can be converted to false, you’ll get the replacement
instead. The rules for converting strings and numbers to Boolean values state
that 0, NaN, and the empty string ("") count as false, while all the other values
count as true. So 0 || -1 produces -1, and "" || "!?" yields "!?".
The && operator works similarly but the other way around. When the value
to its left is something that converts to false, it returns that value, and otherwise
it returns the value on its right.
every statement that needs a semicolon will always get one. I recommend you do the same, at least
until you’ve learned more about the subtleties of missing semicolons.
The first, var (short for “variable”), is the way bindings were declared in
pre-2015 JavaScript. I’ll get back to the precise way it differs from let in the
next chapter. For now, remember that it mostly does the same thing, but we’ll
rarely use it in this book because it has some confusing properties.
The word const stands for constant. It defines a constant binding, which
points at the same value for as long as it lives.
scope, if they are not in a function.
throughout the whole function that they appear in—or throughout the global
new scopes, so old-style bindings, created with the var keyword, are visible
In pre-2015 JavaScript, only functions created
There is a slightly shorter way to create a function binding. When the function
keyword is used at the start of a statement, it works differentl
function square(x) {
return x * x;
}
This is a function declaration.
There’s a third notation for functions, which looks very different from the
others. Instead of the function keyword, it uses an arrow (=>) made up of an
equal sign and a greater-than character (not to be confused with the greaterthan-
or-equal operator, which is written >=).
const power = (base, exponent) => {
let result = 1;
for (let count = 0; count < exponent; count++) {
result *= base;
}
return result;
};
There’s no deep reason to have both arrow functions and function expressions
in the language. Apart from a minor detail, which we’ll discuss in Chapter
6, they do the same thing. Arrow functions were added in 2015, mostly to make
it possible to write small function expressions
JavaScript is extremely broad-minded about the number of arguments you
pass to a function. If you pass too many, the extra ones are ignored. If you
pass too few, the missing parameters get assigned the value undefined.
If you write an = operator after a parameter, followed by an expression, the
value of that expression will replace the argument when it is not given.
function power(base, exponent = 2) {
let result = 1;
for (let count = 0; count < exponent; count++) {
result *= base;
}
return result;
}
It can be useful for a function to accept any number of arguments. For example,
Math.max computes the maximum of all the arguments it is given.
To write such a function, you put three dots before the function’s last parameter,
like this:
function max(...numbers) {
let result = -Infinity;
for (let number of numbers) {
if (number > result) result = number;
}
return result;
}
console.log(max(4, 1, 9, -2));
// → 9
This “spreads” out the array into the function call, passing its elements as
separate arguments. It is possible to include an array like that along with other
arguments, as in max(9, ...numbers, 2).
Square bracket array notation similarly
tags : #resources
source : https://stackoverflow.com/questions/2856059/passing-an-array-as-a-function-parameter-in-javascript
date : 2023-01-11
//use spread paramater to pass conceptheaders as an array otherwise it is passed as a string
// nB : spread paramerter must be last (or only) parameter
logToConsoleAsCsv(separator = SEPARATOR, ...conceptHeaders)
function callMe(...arr){ //valid arguments
alert(arr);
}
function callMe(name, ...arr){ //valid arguments
alert(arr);
}
function callMe(...arr, name){ //invalid arguments
alert(arr);
}
If you need to pass an array as the starting argument you can do:
function callMe(arr, name){
let newArr = [...arr];
alert(newArr);
}
Since each function has its own this binding, whose value depends on the
way it is called, you cannot refer to the this of the wrapping scope in a regular
function defined with the function keyword.
Arrow functions are different—they do not bind their own this but can see
the this binding of the scope around them. Thus, you can do something like
the following code, which references this from inside a local function:
function normalize() {
console.log(this.coords.map(n => n / this.length));
}
normalize.call({coords: [0, 2, 3], length: 5});
// → [0, 0.4, 0.6]
Values of the type object are arbitrary collections of properties. One way to
create an object is by using braces as an expression.
let day1 = {
squirrel: false,
events: ["work", "touched tree", "pizza", "running"]
};
The binary in operator, when applied to a string and an object, tells you
whether that object has a property with that name.
A prototype is another object that is used as a fallback
source of properties. When an object gets a request for a property that it does
not have, its prototype will be searched for the property, then the prototype’s
prototype, and so on.
JavaScript’s prototype system can be interpreted as a somewhat informal take
on an object-oriented concept called classes.
So JavaScript classes are constructor functions with a prototype property. That
is how they work, and until 2015, that was how you had to write them. These
days, we have a less awkward notation.
class Rabbit {
constructor(type) {
this.type = type;
}
speak(line) {
console.log(`The ${this.type} rabbit says '${line}'`);
}
}
let killerRabbit = new Rabbit("killer");
let blackRabbit = new Rabbit("black");
The class keyword starts a class declaration, which allows us to define a
constructor and a set of methods all in a single place.
Class declarations currently allow only methods—properties that hold functions—
to be added to the prototype.
Inside a class declaration, methods that have static written before their
name are stored on the constructor.
Inheritance allows us to build slightly different data types from existing data
types with relatively little work. It is a fundamental part of the object-oriented
tradition, alongside encapsulation and polymorphism. But while the latter two
are now generally regarded as wonderful ideas, inheritance is more controversial.
Whereas encapsulation and polymorphism can be used to separate pieces
of code from each other, reducing the tangledness of the overall program, inheritance
fundamentally ties classes together, creating more tangle.
The fact that something sounds like an object does not
automatically mean that it should be an object in your program. Reflexivel
writing classes for every concept in your application tends to leave you with a
collection of interconnected objects that each have their own internal, changing
state. Such programs are often hard to understand and thus easy to break.
JSON looks similar to JavaScript’s way of writing arrays and objects, with a
few restrictions. All property names have to be surrounded by double quotes,
and only simple data expressions are allowed—no function calls, bindings, or
anything that involves actual computation. Comments are not allowed in
JSON.
A journal entry might look like this when represented as JSON data:
{
"squirrel": false,
"events": ["work", "touched tree", "pizza", "running"]
}
JavaScript gives us the functions JSON.stringify and JSON.parse to convert
data to and from this format. The first takes a JavaScript value and returns
a JSON-encoded string. The second takes such a string and converts it to the
value it encodes.
In Chapter 1 I mentioned that JavaScript strings are encoded as a sequence
of 16-bit numbers. These are called code units. A Unicode character code
was initially supposed to fit within such a unit (which gives you a little over
65,000 characters). When it became clear that wasn’t going to be enough,
many people balked at the need to use more memory per character. To address
these concerns, UTF-16, the format used by JavaScript strings, was invented.
It describes most common characters using a single 16-bit code unit but uses
a pair of two such units for others.
UTF-16 is generally considered a bad idea today. It seems almost intentionally
designed to invite mistakes. It’s easy to write programs that pretend
code units and characters are the same thing. And if your language doesn’t use
two-unit characters, that will appear to work just fine. But as soon as someone
tries to use such a program with some less common Chinese characters,
it breaks. Fortunately, with the advent of emoji, everybody has started using
two-unit characters, and the burden of dealing with such problems is more
fairly distributed.
Unfortunately, obvious operations on JavaScript strings, such as getting their
length through the length property and
Strict mode
JavaScript can be made a little stricter by enabling strict mode. This is done by
putting the string "use strict" at the top of a file or a function body. Here’s
an example:
function canYouSpotTheProblem() {
"use strict";
for (counter = 0; counter < 10; counter++) {
console.log("Happy happy");
}
}
canYouSpotTheProblem();
// → ReferenceError: counter is not defined
Normally, when you forget to put let in front of your binding, as with
counter in the example, JavaScript quietly creates a global binding and uses
that. In strict mode, an error is reported instead. This is very helpful. It should
be noted, though, that this doesn’t work when the binding in question already
exists as a global binding. In that case, the loop will still quietly overwrite the
value of the binding.
Another change in strict mode is that the this binding holds the value
undefined in functions that are not called as methods.
discussed in this book).
features entirely (such as the with statement, which is so wrong it is not further
parameters with the same name and removes certain problematic language
It disallows giving a function multiple
Another way to set a breakpoint is to include a debugger statement (con
sisting
of simply that keyword) in your program. I
systems.
Regular expressions are both terribly awkward and extremely useful. Their
syntax is cryptic, and the programming interface JavaScript provides for them
is clumsy. But they are a powerful
where it needs it and reports a successful match from positions 0 to 4.
It is possible to write regular expressions that will do a lot of backtracking.
This problem occurs when a pattern can match a piece of input in many different
ways. This means the amount of work doubles with each additional character.
For even just a few dozen characters, the resulting match will take practically
forever.
Because of this behavior, we say the repetition operators (+, , ?, and {}
) are greedy, meaning they match as much as they can and backtrack from
there. If you put a question mark after them (+?, ?, ??, {}?), they become
nongreedy and start by matching as little as possible, matching more only when
the remaining pattern does not fit the smaller match.
A lot of bugs in regular expression programs can be traced to unintentionally
using a greedy operator where a nongreedy one would work better. When using
a repetition operator, consider the nongreedy variant first
In fact, many JavaScript projects aren’t even, technically, written in JavaScript.
There are extensions, such as the type checking dialect mentioned in Chapter
8, that are widely used.
To make this possible, they compile their code, translating it from their chosen JavaScript dialect to plain old JavaScript—or even to a past version of JavaScript—so that old browsers can run it.
Including a modular program that consists of 200 different files in a web page produces its own problems. If fetching a single file over the network takes 50 milliseconds, loading the whole program takes 10 seconds, or maybe half that if you can load several files simultaneously. That’s a lot of wasted time. Because fetching a single big file tends to be faster than fetching a lot of tiny
ones, web programmers have started using tools that roll their programs (which they painstakingly split into modules) back into a single big file before they publish it to the Web.
Such tools are called bundlers.
And we can go further. Apart from the number of files, the size of the files also determines how fast they can be transferred over the network. Thus, the JavaScript community has invented minifiers.
So it is not uncommon for the code that you find in an NPM package or that
runs on a web page to have gone through multiple stages of transformation—
converted from modern JavaScript to historic JavaScript, from ES module format
to CommonJS, bundled, and minified. We won’t go into the details of
these tools in this book since they tend to be boring and change rapidly. Just
be aware