Category: JavaScript

  • Get Object Keys in JavaScript: Find, Read, and Iterate

    Get Object Keys in JavaScript: Find, Read, and Iterate

    To get object keys in JavaScript, use JavaScript Object.keys() to list an object’s own enumerable string keys. Use bracket notation to read a property whose name is stored in a variable, and use Object.entries() to process keys and values together.

    Finding a key and accessing a property are separate operations. Object.keys() discovers available names; bracket access retrieves a value after you choose a name. The methods below focus on own properties, so inherited data does not silently enter your results.

    Get object keys in JavaScript with Object.keys()

    Object.keys(source) returns a new array containing the object’s own enumerable property names that are strings. It excludes inherited properties, non-enumerable properties, and symbols. The result is shallow: it lists keys on the source object, not keys inside nested objects.

    • const profile = { name: “Mina”, role: “editor” };
    • Object.keys(profile) returns [“name”, “role”].

    The returned array is useful for displaying field names, checking whether an object has any enumerable data, or building a controlled iteration. An object with no own enumerable string properties produces an empty array.

    Get a key from an object in JavaScript, then read its value

    When you already know a key, do not search the key array to read its value. Dot notation works for a known identifier-like property name, such as profile.name. Bracket notation evaluates an expression, making it the required form for dynamic names, such as profile[field]. It also handles names that are not valid identifiers, including “display-name”.

    const field = “role”; const value = profile[field]; stores “editor” in value. In contrast, profile.field looks for a property literally named field; it does not use the variable’s contents. Reading a missing property returns undefined, whether the missing name is supplied with dot or bracket notation.

    Use JavaScript Object.keys(), Object.values(), and Object.entries()

    JavaScript Object.keys, Object.values(), and Object.entries() use the same selection rule: they include an object’s own enumerable string-keyed properties. They differ in what each returns:

    • Object.keys(profile) returns an array of property names.
    • Object.values(profile) returns the corresponding values, without their names.
    • Object.entries(profile) returns pairs such as [“name”, “Mina”].

    Use Object.values() when only the data matters. Use Object.entries() when each operation needs both the property name and its value:

    for (const [key, value] of Object.entries(profile)) { console.log(key, value); }

    This pattern avoids a second lookup and works naturally with destructuring. It iterates only own enumerable string keys, matching the behavior of Object.keys().

    Check own, symbol, and inherited keys with hasOwn and Reflect.ownKeys()

    Object.hasOwn(object, key) checks whether a property belongs directly to the object. It returns true for an own property even when that property is non-enumerable, and false for an inherited property. It is safer and clearer than calling a possibly overridden object.hasOwnProperty() method.

    • const parent = { inherited: true };
    • const record = Object.create(parent); record.visible = true;
    • Object.hasOwn(record, “visible”) returns true.
    • Object.hasOwn(record, “inherited”) returns false.

    Reflect.ownKeys(record) returns every own property key, including enumerable and non-enumerable string keys plus symbol keys. This is broader than Object.keys(), Object.values(), and Object.entries(), which omit symbols and non-enumerable properties. Use Object.getOwnPropertyNames() for all own string keys, or Object.getOwnPropertySymbols() for own symbol keys.

    A for…in loop is different: it visits enumerable string keys from the object and its prototype chain. If you use one, guard each key with Object.hasOwn(record, key). For own enumerable data, Object.keys() or Object.entries() is usually clearer.

  • How to Check for an Empty Object in JavaScript

    How to Check for an Empty Object in JavaScript

    To check for an empty object in JavaScript, first define empty as “no own enumerable string-keyed properties.” For a value already known to be a plain object, Object.keys(obj).length === 0 is the direct test. To safely check an empty object in JavaScript when input may be null or another type, add guards before calling Object.keys().

    A JavaScript empty object can still have inherited, symbol, or non-enumerable properties, so the result depends on which properties your application considers.

    How to check for an empty object in JavaScript with Object.keys(obj).length === 0

    Object.keys() returns an array containing an object’s own enumerable string keys. An object literal with no such keys produces an empty array:

    const value = {};
    Object.keys(value).length === 0; // true

    An object with an own enumerable property produces a nonzero length:

    const value = { name: “Ada” };
    Object.keys(value).length === 0; // false

    When the input is expected to be an object but may be null, use a type and null guard:

    const isEmpty = value =>
      value !== null &&
      typeof value === “object” &&
      Object.keys(value).length === 0;

    This condition also returns true for arrays, dates, maps, sets, and some class instances that have no enumerable own string properties. Use the stricter plain-object check below when the value’s type is not already controlled.

    Guard an empty JavaScript object check against null, arrays, Map, Set, Date, and class instances

    typeof null is “object”, but Object.keys(null) throws a TypeError. Check for null before the type test. Arrays also have object types, so a separate array check or a plain-object prototype check is needed.

    This function accepts object literals and objects created with a null prototype, while rejecting arrays and built-in or custom instance types:

    const isEmptyPlainObject = value =>
      value !== null &&
      typeof value === “object” &&
      (Object.getPrototypeOf(value) === Object.prototype ||
       Object.getPrototypeOf(value) === null) &&
      Object.keys(value).length === 0;

    An array should usually be tested with value.length === 0. A Map and a Set store data in internal collection slots, so use map.size === 0 or set.size === 0. A Date is a date value rather than an empty record. A class instance may have no own fields while still representing a meaningful domain object; test its required fields or use an instanceof check before applying an emptiness rule.

    What does a JavaScript empty object mean for own, inherited, symbol, and non-enumerable properties?

    Object.keys() counts only own, enumerable, string-named properties. Each category changes the result:

    • Own properties: properties stored directly on the object. Enumerable own properties appear in Object.keys().
    • Inherited properties: properties found on the object’s prototype. They do not appear in Object.keys(), and this is normally desirable for configuration or data objects.
    • Symbol properties: own symbol-keyed properties are not returned by Object.keys(), even when they are enumerable.
    • Non-enumerable properties: own string or symbol properties marked non-enumerable are also excluded.

    For example, an object can have hidden data while appearing empty to Object.keys():

    const value = {};
    Object.defineProperty(value, “id”, { value: 7 });
    Object.keys(value).length === 0; // true

    To count all own string and symbol keys, including non-enumerable keys, use Reflect.ownKeys(value).length === 0. Object.getOwnPropertyNames() includes all own string keys, while Object.getOwnPropertySymbols() returns own symbol keys. A for…in loop is not equivalent to Object.keys() because it can include inherited enumerable properties.

    Choose a definition of emptiness when checking whether an object is empty in JavaScript

    • For a plain data object, define empty as having no own enumerable string keys and use the guarded Object.keys(value).length === 0 test.
    • For an object where symbols or non-enumerable metadata matter, use Reflect.ownKeys(value).length === 0 after validating the value’s type.
    • For collections, use their native size or length: Map.size, Set.size, or array length.
    • For inherited settings, decide explicitly whether the prototype contributes data. Avoid treating inherited properties as own record fields by accident.

    Do not use JSON.stringify(value) === “{}” as a universal emptiness test. Serialization omits symbols, non-enumerable properties, and several values that do not serialize as ordinary object keys. It also says nothing about whether the value is a plain object, so property inspection and type validation are more reliable.

  • JavaScript Not-Equal Operators: !== vs !=

    JavaScript Not-Equal Operators: !== vs !=

    Use !== for most not-equal operators in JavaScript. It performs a strict comparison, so values must have the same type and value to be considered equal. Use != only when you deliberately want JavaScript to convert values before comparing them.

    These operators can produce different results for the same pair. Choosing the right one prevents unexpected matches between numbers, strings, booleans, and nullish values.

    JavaScript Not-Equal Operators: Choose !== or !=

    !== is the strict inequality operator. It is the negation of strict equality: a !== b produces the same result as !(a === b). It returns true when the operands have different types or different values.

    != is the loose inequality operator. It is the negation of loose equality: a != b produces the same result as !(a == b). Before deciding whether values differ, JavaScript may convert one operand to another type.

    For predictable JavaScript not-equal comparisons, prefer !==. Reserve != for cases where that conversion is an intentional part of the condition.

    How does JavaScript strict inequality with !== work?

    Strict inequality checks type and value without coercion. Two numbers with different values are not equal, and a number is not strictly equal to a string containing the same digits.

    • 7 !== 4 is true because the number values differ.
    • 7 !== “7” is true because one operand is a number and the other is a string.
    • “ready” !== “ready” is false because both operands are the same string.
    • null !== undefined is true because they are different types.

    Strict inequality also follows JavaScript’s strict equality rules for special numeric values. In particular, NaN !== NaN is true, while 0 !== -0 is false.

    How does JavaScript not-equal comparison with != handle type coercion?

    Loose inequality applies the abstract equality rules before returning the opposite result. A numeric string can be converted to a number, and boolean values can be converted to numbers. This means operands that look different in source code may compare as equal.

    • 7 != “7” is false. The string is converted to the number 7.
    • 0 != false is false. The boolean is converted to 0.
    • “” != 0 is false. The empty string is converted to 0.
    • null != undefined is false. These two values are treated as equal by loose equality.

    Coercion can be useful when an input is expected to contain a numeric or boolean representation. It can also hide invalid data, so a loose condition should document or clearly reflect that intent.

    Which results change for numbers, strings, null, and NaN?

    Which value pairs make != and !== disagree?

    The operators disagree whenever loose equality converts the operands into matching values or applies its special nullish rule.

    • 5 and “5”: 5 != “5” is false, but 5 !== “5” is true.
    • 0 and false: 0 != false is false, but 0 !== false is true.
    • null and undefined: null != undefined is false, but null !== undefined is true.

    For ordinary unequal values such as 3 and 8, both operators return true. The difference appears when types or special values affect the comparison.

    Why does NaN need an explicit check?

    NaN means “Not-a-Number,” but it is still a number value according to typeof. It is not equal to itself, so both NaN != NaN and NaN !== NaN return true. Testing whether two values differ does not identify NaN specifically.

    Use Number.isNaN(value) for an explicit check. Unlike the global isNaN() function, Number.isNaN() does not first coerce unrelated values such as strings.

    How do you write clear JavaScript not-equal checks?

    • Use value !== expected when both type and value must match.
    • Use typeof value !== “string” when rejecting values of a particular type.
    • Use value !== null when only the literal null should be excluded.
    • Use value != null only when intentionally treating both null and undefined as missing.
    • Convert input explicitly when conversion is required, then compare strictly: Number(input) !== 10.

    In most not-equal checks in JS, !== communicates the intended rule directly and avoids implicit conversion. Choose != only when its coercive behavior is known, tested, and desirable.

  • JavaScript filter: Array.filter() With Practical Examples

    JavaScript filter: Array.filter() With Practical Examples

    JavaScript filter keeps the elements in an array that satisfy a condition. Its main method, Array.filter(), calls a callback for each existing element and returns a new array containing every element whose callback result is truthy.

    Use it for collections with zero, one, or many matches. The original array remains unchanged, so the method is suitable for creating filtered views of data without removing elements from the source.

    How JavaScript filter works

    The JavaScript filter function receives up to three callback arguments: the current element, its index, and the complete array. Most callbacks use only the element:

    Example: const numbers = [3, 8, 12, 15]; const multiples = numbers.filter((element) => element % 3 === 0);

    The returned value is [3, 12, 15]. To access all callback arguments, use this form:

    Example: const firstHalf = numbers.filter((element, index, array) => index < array.length / 2 && element > 5);

    A callback does not need to return the words true or false. Any truthy result keeps the element; false, 0, “”, null, and undefined exclude it. Returning a boolean expression makes the intended rule clearest.

    filter() does not mutate the original array. It creates a new array, although object elements inside it still reference the same objects. If no elements pass the condition, the result is an empty array: [].

    How does the JavaScript filter function select numbers and strings?

    For numbers, write a predicate that describes the allowed value. This example keeps values at least 10:

    Example: const scores = [7, 10, 14, 18]; const passing = scores.filter(score => score >= 10);

    The result is [10, 14, 18], while scores is unchanged. The same pattern works with strings. Combine typeof with a text condition when an array may contain different data types:

    Example: const values = [“JavaScript”, 42, “filter”, null]; const words = values.filter(value => typeof value === “string” && value.length > 5);

    This returns [“JavaScript”, “filter”]. The filter function JavaScript developers use can therefore select by type, length, range, pattern, or any other callback condition.

    How JavaScript Array.filter() handles objects, missing values, and multiple conditions

    For objects, inspect a property inside the callback. This example keeps active users:

    Example: const users = [{ name: “Ana”, active: true }, { name: “Bo”, active: false }, { name: “Cy”, active: true }]; const activeUsers = users.filter(user => user.active === true);

    The result contains Ana and Cy. A missing property evaluates to undefined, so an explicit comparison such as user.active === true safely excludes an object without an active property.

    Filter out missing or invalid values by checking the value before using it:

    Example: const values = [10, undefined, 25, null, 40]; const validNumbers = values.filter(value => typeof value === “number”);

    The result is [10, 25, 40]. For a sparse array with genuinely empty slots, filter() skips those unassigned slots rather than calling the callback for them.

    Use logical operators for compound conditions. This example keeps in-stock products costing no more than 50:

    Example: const products = [{ name: “Pen”, price: 3, inStock: true }, { name: “Bag”, price: 45, inStock: false }, { name: “Lamp”, price: 38, inStock: true }]; const affordable = products.filter(product => product.inStock && product.price <= 50);

    The && operator requires both conditions to pass. Use || when either condition is acceptable, such as selecting products in the “office” or “school” category.

    When should you use the filter function in JavaScript instead of find or map?

    Choose filter() when the required result is an array containing every match. Its result always has array shape, including an empty array when nothing matches.

    Choose find() when you need one element: specifically, the first match. It returns that element or undefined, not an array. Do not use filter() when a single first match is the required result.

    Choose map() when every element should produce a transformed value. It normally returns an array with the same number of elements, whereas filter() removes elements that fail its predicate.