Internal utility functions shared across Vue.js packages for DOM manipulation, type checking, and general utilities
—
Deep equality checking and comparison utilities with special handling for complex data types including dates, arrays, objects, and symbols.
Functions for performing deep equality checks that handle JavaScript's complex equality semantics.
/**
* Perform deep loose equality comparison between two values
* Handles special cases for dates, symbols, arrays, and objects
* @param a - First value to compare
* @param b - Second value to compare
* @returns True if values are loosely equal
*/
function looseEqual(a: any, b: any): boolean;
/**
* Find index of value in array using loose equality comparison
* Uses looseEqual for comparison instead of strict equality
* @param arr - Array to search in
* @param val - Value to find
* @returns Index of value or -1 if not found
*/
function looseIndexOf(arr: any[], val: any): number;Usage Examples:
import { looseEqual, looseIndexOf } from "@vue/shared";
// Basic equality (same as === for primitives)
console.log(looseEqual(1, 1)); // true
console.log(looseEqual("hello", "hello")); // true
console.log(looseEqual(1, "1")); // false (different types)
// Date comparison (compares timestamps)
const date1 = new Date("2023-01-01");
const date2 = new Date("2023-01-01");
const date3 = new Date("2023-01-02");
console.log(looseEqual(date1, date2)); // true (same timestamp)
console.log(looseEqual(date1, date3)); // false (different timestamps)
console.log(date1 === date2); // false (different objects)
// Symbol comparison (always strict)
const sym1 = Symbol("test");
const sym2 = Symbol("test");
const sym3 = sym1;
console.log(looseEqual(sym1, sym2)); // false (different symbols)
console.log(looseEqual(sym1, sym3)); // true (same symbol)
// Array comparison (recursive)
const arr1 = [1, 2, { a: 3 }];
const arr2 = [1, 2, { a: 3 }];
const arr3 = [1, 2, { a: 4 }];
console.log(looseEqual(arr1, arr2)); // true (deep equal)
console.log(looseEqual(arr1, arr3)); // false (nested object differs)
console.log(arr1 === arr2); // false (different array objects)
// Object comparison (recursive)
const obj1 = {
name: "John",
age: 30,
hobbies: ["reading", "coding"],
birth: new Date("1993-01-01")
};
const obj2 = {
name: "John",
age: 30,
hobbies: ["reading", "coding"],
birth: new Date("1993-01-01")
};
const obj3 = {
name: "John",
age: 31,
hobbies: ["reading", "coding"],
birth: new Date("1993-01-01")
};
console.log(looseEqual(obj1, obj2)); // true (deep equal)
console.log(looseEqual(obj1, obj3)); // false (age differs)
// Nested structure comparison
const complex1 = {
users: [
{ id: 1, profile: { name: "Alice", tags: ["admin"] } },
{ id: 2, profile: { name: "Bob", tags: ["user"] } }
],
settings: { theme: "dark", notifications: true }
};
const complex2 = {
users: [
{ id: 1, profile: { name: "Alice", tags: ["admin"] } },
{ id: 2, profile: { name: "Bob", tags: ["user"] } }
],
settings: { theme: "dark", notifications: true }
};
console.log(looseEqual(complex1, complex2)); // true
// Array indexOf with loose equality
const mixedArray = [
1,
"hello",
{ name: "test" },
[1, 2, 3],
new Date("2023-01-01")
];
// Find equivalent values
console.log(looseIndexOf(mixedArray, 1)); // 0
console.log(looseIndexOf(mixedArray, { name: "test" })); // 2
console.log(looseIndexOf(mixedArray, [1, 2, 3])); // 3
console.log(looseIndexOf(mixedArray, new Date("2023-01-01"))); // 4
// Not found
console.log(looseIndexOf(mixedArray, { name: "other" })); // -1
console.log(looseIndexOf(mixedArray, [1, 2, 4])); // -1looseEqual follows these rules in order:
a === b, return truegetTime() if both are datesDate Comparison:
const d1 = new Date("2023-01-01T00:00:00.000Z");
const d2 = new Date("2023-01-01T00:00:00.000Z");
looseEqual(d1, d2); // true - compares timestampsArray vs Non-Array:
looseEqual([1, 2], "1,2"); // false - different types
looseEqual([], ""); // false - different typesObject Property Order:
looseEqual({ a: 1, b: 2 }, { b: 2, a: 1 }); // true - order doesn't matterMissing vs Undefined Properties:
looseEqual({ a: 1 }, { a: 1, b: undefined }); // false - different key countsCircular References:
const circular1: any = { name: "test" };
circular1.self = circular1;
const circular2: any = { name: "test" };
circular2.self = circular2;
// Will cause maximum call stack exceeded error
// looseEqual(circular1, circular2); // ❌ Don't do thisForm Validation:
function hasFormChanged(currentValues: any, originalValues: any) {
return !looseEqual(currentValues, originalValues);
}Array Operations:
function removeByValue(arr: any[], value: any) {
const index = looseIndexOf(arr, value);
if (index > -1) {
arr.splice(index, 1);
}
}Change Detection:
function shouldUpdate(newProps: any, oldProps: any) {
return !looseEqual(newProps, oldProps);
}Install with Tessl CLI
npx tessl i tessl/npm-vue--shared