console.log([] == []); // Output: false
console.log([] == ![]); // Output: true
- Explanation: The first comparison returns
false
because each array is a different object in memory. The second comparison returnstrue
because the right side evaluates tofalse
(![]
isfalse
), and[] == false
istrue
due to type coercion, where the empty array is coerced to a number (0) andfalse
is also coerced to a number (0).
console.log(null == 0); // Output: false
console.log(null > 0); // Output: false
console.log(null >= 0); // Output: true
- Explanation:
null
is not equal to0
due to type coercion rules, butnull >= 0
istrue
becausenull
is converted to0
in relational comparison.
console.log(typeof null); // Output: "object"
console.log(typeof NaN); // Output: "number"
- Explanation:
typeof null
returning"object"
is a well-known JavaScript quirk, considered a bug for historical reasons.NaN
(Not-a-Number) is technically of type"number"
.
console.log([1, 2] + [3, 4]); // Output: "1,23,4"
- Explanation: Arrays are converted to strings and concatenated, resulting in the unexpected string
"1,23,4"
.
console.log({} + []); // Output: "[object Object]"
console.log([] + {}); // Output: "[object Object]"
- Explanation: When adding an object and an array, both operands are converted to their string representations and then concatenated.
let num = '5';
console.log(++num); // Output: 6
- Explanation: The pre-increment operator coerces the string
'5'
to a number and increments it.
console.log([..."Hello"]); // Output: ["H", "e", "l", "l", "o"]
- Explanation: The spread operator (
...
) splits the string into an array of its individual characters.
function add(a = 1, b = a) {
return a + b;
}
console.log(add(undefined, 2)); // Output: 3
- Explanation: Passing
undefined
to a function parameter that has a default value causes the default value to be used.
console.log(0.1 + 0.2 === 0.3); // Output: false
- Explanation: Due to floating-point arithmetic and precision issues in JavaScript,
0.1 + 0.2
does not exactly equal0.3
.
console.log(void(0)); // Output: undefined
- Explanation: The
void
operator evaluates the expression and then returnsundefined
. It's often used to explicitly returnundefined
from expressions.
console.log(typeof foo); // Output: "function"
console.log(typeof bar); // Output: "undefined"
function foo() {}
var bar = function() {};
- Explanation: Function declarations are hoisted completely, meaning both the declaration and the definition are hoisted to the top. However, function expressions (like
bar
) are only hoisted in their declaration part, not their initialization.
console.log(NaN === NaN); // Output: false
- Explanation: In JavaScript,
NaN
(Not-a-Number) is the only value that is not equal to itself. To check if a value isNaN
, useNumber.isNaN()
instead.
function example() {
return arguments[0];
}
console.log(example(1, 2, 3)); // Output: 1
- Explanation: Inside a function,
arguments
is an Array-like object accessible that contains the values of the arguments passed to that function. It's not an actual array, though, so it doesn't have array methods.
console.log('5' + 3); // Output: "53"
console.log('5' - 3); // Output: 2
- Explanation: The
+
operator can serve as both addition and string concatenation, leading to type coercion into a string when one of the operands is a string. The-
operator, however, only works with numbers, so it coerces the string'5'
into a number before performing subtraction.
function C(){}
function D(){}
var o = new C();
console.log(o instanceof C); // Output: true
console.log(o instanceof D); // Output: false
- Explanation: The
instanceof
operator tests whether the prototype property of a constructor appears anywhere in the prototype chain of an object.
console.log(typeof null); // Output: "object"
- Explanation: This is a long-standing bug in JavaScript, where
typeof null
returns"object"
.null
is actually considered to be of its own type.
var obj = {a: 1};
delete obj.a;
console.log(obj.a); // Output: undefined
- Explanation: The
delete
operator removes a property from an object. If the property existed,delete
returnstrue
; otherwise, it returnsfalse
.
function returnObject() {
return
{
a: 1
};
}
console.log(returnObject()); // Output: undefined
- Explanation: JavaScript automatically inserts a semicolon after the
return
statement, causing the function to returnundefined
instead of the object.
var arr = [1,2,3];
console.log(2 in arr); // Output: true
console.log(3 in arr); // Output: false
- Explanation: The
in
operator checks if a property exists in an object. With arrays, it checks if an index exists, not the value. Since arrays are zero-indexed,2
is a valid index, but3
is not.
var numbers = [10, 5, 11];
numbers.sort();
console.log(numbers); // Output: [10, 11, 5]
- Explanation: By default,
sort()
converts elements to strings and compares their UTF-16 character sequences. To sort numbers numerically, you must provide a compare function.
console.log(0 == false); // Output: true
console.log(0 === false); // Output: false
console.log(0 == '0'); // Output: true
console.log(0 === '0'); // Output: false
- Explanation: The
==
operator performs type coercion, where0
,false
, and'0'
can be considered equal. The===
operator, however, checks for both value and type, so0
is not strictly equal tofalse
or'0'
.
if (true) {
var varVariable = 'This is var';
let letVariable = 'This is let';
}
console.log(varVariable); // Output: "This is var"
console.log(letVariable); // ReferenceError: letVariable is not defined
- Explanation: Variables declared with
var
are function-scoped (or globally-scoped if declared outside of a function), whilelet
andconst
are block-scoped. This meansletVariable
is not accessible outside of theif
block.
console.log(typeof undefined); // Output: "undefined"
console.log(typeof true); // Output: "boolean"
console.log(typeof 42); // Output: "number"
console.log(typeof "42"); // Output: "string"
console.log(typeof {}); // Output: "object"
console.log(typeof Symbol()); // Output: "symbol"
console.log(typeof null); // Output: "object" (this is considered a bug in JavaScript)
- Explanation: The
typeof
operator returns a string indicating the type of the unevaluated operand. The case oftypeof null
returning"object"
is a known, longstanding bug in JavaScript.
for (var i = 1; i <= 3; i++) {
setTimeout(function() {
console.log(i); // Output: 4 (three times)
}, 0);
}
- Explanation: Because
var
is function-scoped, by the time thesetTimeout
function executes, the loop has completed, andi
has a value of4
. To log1
,2
,3
as expected, you can uselet
in the loop declaration, which is block-scoped.
function whatIsThis() {
return this;
}
console.log(whatIsThis()); // Output: Window object (or global object in non-browser environment)
const obj = {
whatIsThis: whatIsThis
};
console.log(obj.whatIsThis()); // Output: obj
- Explanation: The value of
this
is determined by how a function is called. In the first case,whatIsThis
is called in the global context, sothis
refers to the global object (window
in browsers). In the second case,whatIsThis
is called as a method ofobj
, sothis
refers toobj
.
console.log(0.1 + 0.2); // Output: 0.30000000000000004
- Explanation: JavaScript uses binary floating-point arithmetic, which can lead to precision issues with decimal numbers. This is because some fractions cannot be represented exactly in binary.
function greet({name = 'Anonymous'} = {}) {
return `Hello, ${name}!`;
}
console.log(greet()); // Output: "Hello, Anonymous!"
console.log(greet({name: 'John'})); // Output: "Hello, John!"
- Explanation: This function uses destructuring with default parameters. If no argument is passed, it defaults to an empty object
{}
, and ifname
is not provided in the object, it defaults to'Anonymous'
.
let a = 5;
let b = 10;
console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`); // Output: "Fifteen is 15 and not 20."
- Explanation: Template literals allow embedded expressions. These expressions are evaluated, and the resulting values are converted into strings and part of the final string.
let [first, , third] = ["Spades", "Diamonds", "Hearts"];
console.log(first); // Output: "Spades"
console.log(third); // Output: "Hearts"
- Explanation: Destructuring allows binding using pattern matching, with support for matching arrays and objects. It's possible to skip elements in an array by leaving a gap in the destructuring assignment.
function multiply(a, b = 1) {
return a * b;
}
console.log(multiply(5)); // Output: 5
- Explanation: Default function parameters allow named parameters to be initialized with default values if no value or
undefined
is passed.
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3)); // Output: 6
- Explanation: Rest parameters allow us to represent an indefinite number of arguments as an array, providing a way to handle function parameters more flexibly.
let numbers = [1, 2, 3, 4];
let squares = numbers.map(num => num * num);
console.log(squares); // Output: [1, 4, 9, 16]
numbers.forEach((num, index) => {
numbers[index] = num * num;
});
console.log(numbers); // Output: [1, 4, 9, 16]
- Explanation:
.map()
returns a new array containing the results of applying a function to every element in the original array..forEach()
performs a specified action for each element in an array but does not return a value.
let a = null;
let b = "Hello World";
console.log(a || b); // Output: "Hello World"
console.log(a && b); // Output: null
- Explanation: JavaScript supports short-circuit evaluation.
||
returns the first truthy value or the last value if none are truthy.&&
returns the first falsy value or the last value if all are truthy.
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
console.log(arr1); // Output: [0, 1, 2, 3, 4, 5]
- Explanation: The spread operator
...
allows an iterable (e.g., array) to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.
const name = "John Doe";
const age = 30;
const user = { name, age };
console.log(user); // Output: { name: "John Doe", age: 30 }
- Explanation: ES6 allows you to eliminate the redundancy of having to write the property name and variable name when they are the same.
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 1000);
});
promise.then(
result => console.log(result), // Output: "done" after 1 second
error => console.log(error) // doesn't run
);
- Explanation: A
Promise
is an object representing the eventual completion or failure of an asynchronous operation..then()
takes two arguments: a callback for success and another for failure.
async function helloAsync() {
return "Hello Async!";
}
helloAsync().then(value => console.log(value)); // Output: "Hello Async!"
- Explanation:
async
functions allow you to work with promises in a more comfortable way. Theawait
keyword can be used inside anasync
function to pause the execution until the promise is settled. The function then resumes execution and returns the resolved value.
async function fetchWithErrorHandling() {
try {
let response = await fetch('https://nonexistent.url');
let data = await response.json();
console.log(data);
} catch (error) {
console.error("Error:", error);
}
}
fetchWithErrorHandling(); // Output: Error: [Error details]
- Explanation: The
try...catch
block in anasync
function allows for elegant handling of rejected promises. If an error occurs during anyawait
call within thetry
block, the control moves to thecatch
block.
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}!`);
}
}
let john = new Person("John");
john.greet(); // Output: "Hello, my name is John!"
- Explanation: ES6 introduced
class
as syntactic sugar over JavaScript's existing prototype-based inheritance. Theclass
syntax provides a clearer and more concise way to create objects and deal with inheritance.
let mySet = new Set([1, 2, 3, 4, 4, 4]);
console.log(mySet.size); // Output: 4
mySet.add(5);
console.log(mySet.has(5)); // Output: true
mySet.delete(1);
console.log(mySet.size); // Output: 4
- Explanation:
Set
is a collection of unique values. Duplicate values are not added to a set, which makes it useful for creating collections of unique items.
let myMap = new Map();
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
console.log(myMap.size); // Output: 2
console.log(myMap.get('key1')); // Output: "value1"
myMap.delete('key1');
console.log(myMap.has('key1')); // Output: false
- Explanation: A
Map
holds key-value pairs where the keys can be any datatype. AMap
remembers the original insertion order of the keys, which differentiates it from an Object.
function tag(strings, ...values) {
console.log(strings); // ["Hello ", ", you have ", " unread messages"]
console.log(values); // ["John", 12]
return "Processed template string";
}
let user = "John";
let messages = 12;
console.log(tag`Hello ${user}, you have ${messages} unread messages`);
// Output: Processed template string
- Explanation: Tagged template literals allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The subsequent arguments are related to the expressions.
let target = {};
let proxy = new Proxy(target, {
get(target, prop, receiver) {
return `Property ${prop} doesn't exist.`;
}
});
console.log(proxy.test); // Output: Property test doesn't exist.
- Explanation: The
Proxy
object is used to define custom behavior for fundamental operations (e.g., property lookup, assignment, enumeration, function invocation, etc.). Here, any attempt to access a property on the proxy that doesn't exist in the target returns a custom message.
const obj = { x: 1, y: 2 };
console.log(Reflect.has(obj, 'x')); // Output: true
Reflect.deleteProperty(obj, 'y');
console.log(obj); // Output: { x: 1 }
- Explanation: The
Reflect
API provides methods for interceptable JavaScript operations. Here,Reflect.has
checks if an object has a certain property, andReflect.deleteProperty
removes a property from an object.
const uniqueId = Symbol('id');
const obj = {
[uniqueId]: '12345'
};
console.log(obj[uniqueId]); // Output: "12345"
console.log(Symbol('id') === Symbol('id')); // Output: false
- Explanation: Symbols are a primitive data type introduced in ES6, used to create unique identifiers for object properties. Each time
Symbol()
is called, a new, unique symbol is created.
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const generator = generatorFunction();
console.log(generator.next().value); // Output: 1
console.log(generator.next().value); // Output: 2
console.log(generator.next().value); // Output: 3
- Explanation: Generators are a special class of functions that simplify the creation of iterators. A generator can pause midway and then continue from where it paused.
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
(async () => {
for await (const num of asyncGenerator()) {
console.log(num);
}
})(); // Output: 1, then 2, then 3
- Explanation:
async
generators combine generators and promises. They allow you toyield
promises that are awaited in a for-await-of loop.
const obj = { a: { b: { c: 1 } } };
console.log(obj.a?.b?.c); // Output: 1
console.log(obj.x?.y?.z); // Output: undefined
- Explanation: Optional chaining (
?.
) permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid.
const foo = null ?? 'default string';
console.log(foo); // Output: "default string"
const baz = 0 ?? 42;
console.log(baz); // Output: 0
- Explanation: The nullish coalescing operator (
??
) returns the right-hand side operand when the left-hand side operand isnull
orundefined
, and otherwise returns the left-hand side operand.
(async () => {
if (condition) {
const module = await import('/path/to/module.js');
module.doSomething();
}
})();
- Explanation: Dynamic imports load modules dynamically with a call to
import()
returning a promise. This is useful for conditionally loading modules and for code splitting in applications.
const largeNumber = BigInt(9007199254740991);
const anotherLargeNumber = 9007199254740991n;
console.log(largeNumber + anotherLargeNumber); // Output: 18014398509481982n
- Explanation:
BigInt
is a built-in object that provides a way to represent whole numbers larger than 2^53 - 1, which is the largest number JavaScript can reliably represent with theNumber
primitive.
const array = [10, 20, 30, 40, 50];
console.log(array.at(-1)); // Output: 50
const string = 'JavaScript';
console.log(string.at(0)); // Output: "J"
- Explanation: The
at()
method takes an integer value and returns the item at that index, allowing for positive and negative integers. Negative integers count back from the last item in the array or string.
n enhance your coding patterns and problem-solving strategies, especially in modern JavaScript development. Understanding these concepts can give you a significant edge in interviews and practical coding tasks.
class MyClass {
#privateField = 'private value';
getPrivateField() {
return this.#privateField;
}
}
const instance = new MyClass();
console.log(instance.getPrivateField()); // Output: "private value"
console.log(instance.#privateField); // SyntaxError: Private field '#privateField' must be declared in an enclosing class
- Explanation: Private class fields are a part of the class fields proposal. They are declared with a
#
prefix and can only be accessed within the class body. Attempting to access them outside the class results in a syntax error.
// In a module script
const dynamicValue = await fetch('https://api.example.com/data').then(response => response.json());
console.log(dynamicValue); // Output depends on the fetched data
- Explanation: Top-level
await
allows modules to act as big async functions. With it, you can useawait
at the top level of a module, pausing the execution of the module code until the awaited promise is resolved.
let a = 1;
let b = 0;
a &&= 2;
console.log(a); // Output: 2
b ||= 5;
console.log(b); // Output: 5
b ??= 7;
console.log(b); // Output: 5
- Explanation: Logical assignment operators combine logical operations with assignment.
&&=
only assigns if the left-hand side is truthy,||=
assigns if the left-hand side is falsy, and??=
assigns if the left-hand side isnull
orundefined
.
const nestedArray = [1, [2, 3], [4, [5]]];
console.log(nestedArray.flat()); // Output: [1, 2, 3, 4, [5]]
console.log(nestedArray.flat(2)); // Output: [1, 2, 3, 4, 5]
const array = [1, 2, 3, 4];
console.log(array.flatMap(x => [x, x * 2])); // Output: [1, 2, 2, 4, 3, 6, 4, 8]
- Explanation:
flat()
creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.flatMap()
first maps each element using a mapping function, then flattens the result into a new array. It's essentiallymap()
followed byflat()
of depth 1.
const promises = [
Promise.resolve('success'),
Promise.reject('error'),
Promise.resolve('success2')
];
Promise.allSettled(promises).then(results => console.log(results));
// Output: Array of objects, each indicating the status ("fulfilled" or "rejected") and value or reason
- Explanation:
Promise.allSettled()
takes an iterable of promises and returns a promise that resolves after all the given promises have either resolved or rejected, with an array of objects that each describe the outcome of each promise.
console.log(globalThis); // Output: The global object (varies by environment)
- Explanation:
globalThis
provides a standard way to access the globalthis
value across environments, including the browser, Node.js, and web workers, where different global objects (window
,global
,self
) exist.
const string = 'test1test2';
const regex = /t(e)(st(\d?))/g;
const matches = [...string.matchAll(regex)];
console.log(matches[0]); // Output: Array with the whole match and capturing groups for the first match
console.log(matches[1]); // Output: Array with the whole match and capturing groups for the second match
- Explanation:
matchAll()
returns an iterator of all results matching a string against a regular expression, including capturing groups.
// German locale
const date = new Date(Date.UTC(2020, 2, 20, 3, 23, 16, 738));
console.log(new Intl.DateTimeFormat('de-DE').format(date)); // Output: "20.3.2020" for German locale
- Explanation: The
Intl
object is the namespace for the ECMAScript Internationalization API, which provides language-sensitive string comparison, number formatting, and date and time formatting.Intl.NumberFormat
andIntl.DateTimeFormat
are constructors for objects that enable language-sensitive number and date/time formatting, respectively.
let obj = {};
const weakRef = new WeakRef(obj);
(function() {
const derefObj = weakRef.deref();
if (derefObj) {
console.log("Object is still alive!");
} else {
console.log("Object has been garbage collected.");
}
})();
obj = null; // Now obj can be garbage collected at some point in the future
const registry = new FinalizationRegistry(value => {
console.log(`The object with reference ${value} has been garbage collected.`);
});
registry.register(obj, 'obj');
- Explanation:
WeakRef
allows you to hold a weak reference to another object, without preventing that object from being garbage-collected.FinalizationRegistry
provides a way to register a callback to be invoked after an object has been garbage collected. Note that the use of these features should be limited as they introduce potential memory management and performance issues.
const value1 = 9007199254740991n;
const value2 = BigInt(9007199254740991);
console.log(value1 + value2); // Output: 18014398509481982n
console.log(value1 * value2); // Output: 81129638414606663681390495662081n
- Explanation:
BigInt
is a built-in object that provides a way to represent whole numbers larger than 2^53 - 1, which is the largest number JavaScript can reliably represent with theNumber
primitive.BigInt
can be used for arbitrarily large integers.
// file: math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
// file: main.js
import { add, subtract } from './math.js';
console.log(add(2, 3)); // Output: 5
console.log(subtract(5, 2)); // Output: 3
- Explanation: ES6 modules allow you to organize and reuse code across your projects.
export
is used to expose functions, objects, or primitives from a module so they can be used by other programs with theimport
statement.
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // Output: 15
- Explanation: The
reduce()
method executes a reducer function on each element of the array, resulting in a single output value. It's particularly useful for aggregating or accumulating values from an array.
const validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // Output: 100
person.age = 'young'; // Throws TypeError: The age is not an integer
person.age = 300; // Throws RangeError: The age seems invalid
- Explanation:
Proxy
objects enable you to create a proxy for another object, which can intercept and redefine fundamental operations for that object, such as property lookup, assignment, enumeration, function invocation, etc. This example demonstrates using aProxy
for basic property validation.
I'm glad you're finding these examples useful! Here are more JavaScript concepts and examples to explore:
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 500, 'one'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'two'));
Promise.race([promise1, promise2]).then(value => {
console.log(value); // Output: "two"
});
- Explanation:
Promise.race()
takes an iterable of Promise objects and returns a single Promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // Output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // Output: 42
- Explanation:
bind()
creates a new function that, when called, has itsthis
keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
const obj = {
prop: 42
};
Object.freeze(obj);
obj.prop = 33;
console.log(obj.prop); // Output: 42
const obj2 = {
prop: 42
};
Object.seal(obj2);
obj2.prop = 33;
console.log(obj2.prop); // Output: 33
obj2.newProp = 'test';
console.log(obj2.newProp); // Output: undefined
- Explanation:
Object.freeze()
makes an object immutable, preventing new properties from being added to it and existing properties from being removed or changed.Object.seal()
prevents new properties from being added to an object and marks all existing properties as non-configurable, but allows the modification of existing property values.
const array = [1, 2, 3];
console.log(array.includes(2)); // Output: true
console.log(array.includes(4)); // Output: false
console.log(array.includes(3, 3)); // Output: false
- Explanation:
includes()
determines whether an array includes a certain value among its entries, returningtrue
orfalse
as appropriate. It has an optional second argument to specify the position in the array at which to begin the search.
const str = 'Saturday night plans';
console.log(str.startsWith('Sat')); // Output: true
console.log(str.endsWith('plans')); // Output: true
console.log(str.startsWith('Sat', 3)); // Output: false
- Explanation:
startsWith()
checks if the string starts with the specified substring, returningtrue
orfalse
as appropriate. Similarly,endsWith()
checks if the string ends with the specified substring. Both methods have an optional second argument to specify the position at which to start or end the search.
const set = new Set(['foo', 'bar', 'baz', 'foo']);
const array = Array.from(set);
console.log(array); // Output: ["foo", "bar", "baz"]
- Explanation:
Array.from()
creates a new, shallow-copied Array instance from an array-like or iterable object. This example demonstrates converting aSet
to anArray
, removing duplicate values in the process.
const obj = { a: 'somestring', b: 42 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
// Output: "a: somestring", "b: 42"
console.log(Object.values(obj)); // Output: ["somestring", 42]
- Explanation:
Object.entries()
returns an array of a given object's own enumerable string-keyed property[key, value]
pairs.Object.values()
returns an array of a given object's own enumerable property values.
const array = [1, 2, 3, 4, 5];
const even = (element) => element % 2 === 0;
console.log(array.some(even)); // Output: true
console.log(array.every(even)); // Output: false
- Explanation:
Array.prototype.some()
tests whether at least one element in the array passes the test implemented by the provided function, returningtrue
orfalse
.Array.prototype.every()
tests whether all elements in the array pass the test implemented by the provided function.
console.log(Number.isFinite(Infinity)); // Output: false
console.log(Number.isFinite(-Infinity)); // Output: false
console.log(Number.isFinite(NaN)); // Output: false
console.log(Number.isFinite(123)); // Output: true
console.log(Number.isNaN(NaN)); // Output: true
console.log(Number.isNaN(123)); // Output: false
console.log(Number.isNaN('NaN')); // Output: false
console.log(Number.isNaN(undefined)); // Output: false
- Explanation:
Number.isFinite()
determines whether the passed value is a finite number. Unlike the globalisFinite()
, it doesn't forcibly convert the parameter to a number. This ensures only values of the type number, that are also finite, returntrue
.Number.isNaN()
determines whether the passed value isNaN
and its type isNumber
. It is a more robust version of the original globalisNaN()
.
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // Output: { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // Output: { a: 1, b: 4, c: 5 }
- Explanation:
Object.assign()
is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
function greet(greeting, punctuation) {
return greeting + ', ' + this.user + punctuation;
}
const context = { user: 'John' };
console.log(greet.apply(context, ['Hello', '!'])); // Output: "Hello, John!"
console.log(greet.call(context, 'Hello', '!')); // Output: "Hello, John!"
const boundGreet = greet.bind(context, 'Hello', '!');
console.log(boundGreet()); // Output: "Hello, John!"
- Explanation:
apply()
,call()
, andbind()
are used to set thethis
context of a function.apply()
takes arguments as an array,call()
takes arguments separately, andbind()
returns a new function, allowing you to pass in a this array and any number of arguments.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // Output: [3, 42, "foo"]
});
- Explanation:
Promise.all()
takes an iterable of promises as an input, and it returns a single Promise that resolves when all of the promises in the iterable have resolved or when the iterable contains no promises. It rejects with the reason of the first promise that rejects.
const mySet = new Set();
mySet.add(1);
mySet.add(5);
mySet.add(5); // Duplicate, not added
mySet.has(1); // Output: true
mySet.has(3); // Output: false
mySet.size; // Output: 2
mySet.delete(5);
console.log(mySet.size); // Output: 1
- Explanation: A
Set
is a collection of unique values.Set
objects allow you to store unique values of any type, whether primitive values or object references.Set
is useful for ensuring the uniqueness of the elements.
Certainly! Here are additional JavaScript examples to further enrich your understanding:
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // Output: [2, 4, 6]
- Explanation:
filter()
creates a new array with all elements that pass the test implemented by the provided function. It's a great way to derive a subset of elements based on conditions.
const array = [[0, 1], [2, 3], [4, 5]].reduceRight(
(accumulator, currentValue) => accumulator.concat(currentValue)
);
console.log(array); // Output: [4, 5, 2, 3, 0, 1]
- Explanation: Similar to
reduce()
,reduceRight()
applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value. It's particularly useful when order of operation is important in the reduction.
function whoCalledMe() {
console.log("Caller is:", whoCalledMe.caller);
}
function callerFunction() {
whoCalledMe();
}
callerFunction();
// Output: Caller is: function callerFunction() { whoCalledMe(); }
- Explanation: The
caller
property of a function returns the function that invoked the specified function. It's a non-standard feature and its use is discouraged in strict mode and new JavaScript modules.
const object = { a: 1, b: 2, c: 3 };
console.log(Object.getOwnPropertyNames(object)); // Output: ["a", "b", "c"]
- Explanation:
Object.getOwnPropertyNames()
returns an array of all properties (including non-enumerable properties except for those which use Symbol) found directly in a given object.
const greeting = ' Hello world! ';
console.log(greeting.trimStart()); // Output: "Hello world! "
console.log(greeting.trimEnd()); // Output: " Hello world!"
- Explanation:
trimStart()
removes whitespace from the beginning of a string, andtrimEnd()
removes whitespace from the end. They are more specific versions oftrim()
which removes whitespace from both ends of a string.
const url = new URL('https://example.com:8000/path/name?query=123#hash');
console.log(url.hostname); // Output: "example.com"
console.log(url.pathname); // Output: "/path/name"
console.log(url.search); // Output: "?query=123"
console.log(url.hash); // Output: "#hash"
console.log(url.port); // Output: "8000"
- Explanation: The
URL
constructor creates and returns a URL object representing the URL defined by the parameters. It provides properties that allow easy access to the parts of the URL.
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
const result = inventory.find(fruit => fruit.name === 'cherries');
console.log(result); // Output: { name: 'cherries', quantity: 5 }
- Explanation:
find()
returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function,undefined
is returned.
new Promise((resolve, reject) => {
setTimeout(() => resolve("result"), 2000)
})
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log("Promise finished."));
// Output: "result" followed by "Promise finished."
- Explanation:
finally()
returns a Promise. When the promise is settled, i.e., either fulfilled or rejected, the specified callback function is executed. This provides a way for code to be run whether the promise was successfully fulfilled or rejected.
improve your JavaScript coding skills and problem-solving capabilities. Here are more examples to explore:
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude);
console.log(position.coords.longitude);
});
- Explanation: The
navigator.geolocation
object provides access to the location of the device. This can be used to get the current position of the device.
const element = document.querySelector('.my-class');
console.log(element); // Output: the first element with the class "my-class"
const elements = document.querySelectorAll('.my-class');
console.log(elements.length); // Output: total number of elements with the class "my-class"
- Explanation:
document.querySelector
returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found,null
is returned.document.querySelectorAll
returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
localStorage.setItem('key', 'value');
console.log(localStorage.getItem('key')); // Output: "value"
sessionStorage.setItem('sessionKey', 'sessionValue');
console.log(sessionStorage.getItem('sessionKey')); // Output: "sessionValue"
- Explanation: Web Storage API provides mechanisms by which browsers can securely store key/value pairs.
localStorage
is for storing data with no expiration date, and the data will not be deleted when the browser is closed.sessionStorage
is for storing data that gets cleared when the page session ends.
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
- Explanation: The
fetch
API provides an interface for fetching resources (including across the network). It will seem familiar if you've used XMLHttpRequest, but the new API provides a more powerful and flexible feature set.
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
fetchData();
- Explanation: This example shows how to use
async
andawait
with thefetch
API for making asynchronous HTTP requests. This syntax provides a more straightforward way to handle promises.
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months); // Output: ["Dec", "Feb", "Jan", "March"]
const array = [1, 30, 4, 21, 100000];
array.sort((a, b) => a - b);
console.log(array); // Output: [1, 4, 21, 30, 100000]
- Explanation: The
sort()
method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.
const numbers = [1, 4, 9];
const roots = numbers.map(Math.sqrt);
console.log(roots); // Output: [1, 2, 3]
numbers.forEach((number, index) => {
console.log(`Index: ${index}, Value: ${number}`);
});
// Output: "Index: 0, Value: 1", "Index: 1, Value: 4", "Index: 2, Value: 9"
- Explanation:
map()
creates a new array populated with the results of calling a provided function on every element in the calling array.forEach()
executes a provided function once for each array element.
Certainly! Let's dive into more JavaScript concepts and examples to broaden your understanding:
const user = { name: 'John Doe', age: 30 };
const { name, age } = user;
console.log(name); // Output: "John Doe"
console.log(age); // Output: 30
const colors = ['red', 'green', 'blue'];
const [firstColor, secondColor] = colors;
console.log(firstColor); // Output: "red"
console.log(secondColor); // Output: "green"
- Explanation: Destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
const greeting = `Hello`;
const name = `John`;
console.log(`${greeting}, ${name}!`); // Output: "Hello, John!"
- Explanation: Template literals provide an easy way to interpolate variables and expressions into strings. The method is identified by the use of backticks rather than quotes.
function greet(name = 'Guest') {
return `Hello, ${name}!`;
}
console.log(greet('John')); // Output: "Hello, John!"
console.log(greet()); // Output: "Hello, Guest!"
- Explanation: Default function parameters allow named parameters to be initialized with default values if no value or
undefined
is passed.
const parts = ['shoulders', 'knees'];
const body = ['head', ...parts, 'toes'];
console.log(body); // Output: ["head", "shoulders", "knees", "toes"]
- Explanation: The spread operator
...
allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.
function sum(...numbers) {
return numbers.reduce((prev, current) => prev + current, 0);
}
console.log(sum(1, 2, 3)); // Output: 6
- Explanation: Rest parameters allow us to represent an indefinite number of arguments as an array, providing a way to handle function parameters more flexibly.
const add = (a, b) => a + b;
console.log(add(5, 3)); // Output: 8
const numbers = [1, 2, 3];
const doubled = numbers.map(number => number * 2);
console.log(doubled); // Output: [2, 4, 6]
- Explanation: Arrow functions provide a concise syntax for writing function expressions. They utilize the
=>
syntax and are often more readable and succinct.
function fetchData() {
return new Promise(resolve => setTimeout(() => resolve("data"), 1000));
}
async function main() {
const data = await fetchData();
console.log(data); // Output: "data" after 1 second
}
main();
- Explanation: Promises are used to handle asynchronous operations in JavaScript. They are used to handle asynchronous computations which can then be composed with callbacks.
async
/await
syntax provides a more comfortable abstraction over working with promises, allowing asynchronous code to be written in a more synchronous fashion.
// file: math.js
export const add = (a, b) => a + b;
// file: app.js
import { add } from './math.js';
console.log(add(2, 3)); // Output: 5
- Explanation: JavaScript modules allow you to break up your code into separate files, making it more manageable and maintainable. This also allows you to reuse code across your projects. ES6 introduced a standard module system that supports exporting and importing values between modules.