Internal utility functions shared across Vue.js packages for DOM manipulation, type checking, and general utilities
—
General-purpose utilities for object manipulation, array operations, and data structure handling. These functions provide safe and consistent ways to work with JavaScript objects and arrays.
Core utilities for working with objects and their properties.
/**
* Alias for Object.assign - merge objects
* @param target - Target object to merge into
* @param sources - Source objects to merge from
* @returns Merged target object
*/
const extend: typeof Object.assign;
/**
* Define a property on an object with specific descriptor options
* @param obj - Object to define property on
* @param key - Property key (string or symbol)
* @param value - Property value
* @param writable - Whether property is writable (default: false)
*/
function def(
obj: object,
key: string | symbol,
value: any,
writable?: boolean
): void;Utilities for safely manipulating arrays.
/**
* Remove element from array by value (mutates array)
* Uses indexOf to find element, then splices it out
* @param arr - Array to remove element from
* @param el - Element to remove
*/
function remove<T>(arr: T[], el: T): void;
/**
* Invoke array of functions with provided arguments
* Safely calls each function in the array with the same arguments
* @param fns - Array of functions to invoke
* @param arg - Arguments to pass to each function
*/
function invokeArrayFns(fns: Function[], ...arg: any[]): void;Utilities for comparing values and detecting changes.
/**
* Compare if value has changed, accounting for NaN equality
* Uses Object.is for comparison (handles NaN and -0/+0 correctly)
* @param value - New value
* @param oldValue - Old value to compare against
* @returns True if values are different
*/
function hasChanged(value: any, oldValue: any): boolean;Utilities for converting values to numbers with different behaviors.
/**
* Loose number conversion - used for .number modifier in v-model
* "123-foo" will be parsed to 123, "abc" remains "abc"
* @param val - Value to convert
* @returns Parsed number or original value if not numeric
*/
function looseToNumber(val: any): any;
/**
* Strict number conversion for number-like strings only
* "123-foo" will be returned as-is, "123" becomes number 123
* @param val - Value to convert
* @returns Number if val is numeric string, otherwise original value
*/
function toNumber(val: any): any;Commonly used constant values and utility functions.
/**
* Empty object - frozen in development, regular in production
*/
const EMPTY_OBJ: { readonly [key: string]: any };
/**
* Empty array - frozen in development, regular in production
*/
const EMPTY_ARR: readonly never[];
/**
* No-operation function that returns undefined
*/
const NOOP: () => void;
/**
* Function that always returns false
*/
const NO: () => false;Usage Examples:
import {
extend, def, remove, invokeArrayFns, hasChanged,
EMPTY_OBJ, EMPTY_ARR, NOOP, NO
} from "@vue/shared";
// Object merging with extend
const target = { a: 1, b: 2 };
const source1 = { b: 3, c: 4 };
const source2 = { c: 5, d: 6 };
const merged = extend(target, source1, source2);
console.log(merged); // { a: 1, b: 3, c: 5, d: 6 }
console.log(merged === target); // true (mutates target)
// Property definition
const obj = {};
def(obj, "hiddenProp", "secret", false); // not writable
def(obj, "writableProp", "public", true); // writable
console.log(obj.hiddenProp); // "secret"
console.log(Object.getOwnPropertyDescriptor(obj, "hiddenProp"));
// { value: "secret", writable: false, enumerable: false, configurable: true }
// Array element removal
const items = ["a", "b", "c", "b", "d"];
remove(items, "b"); // Removes first occurrence
console.log(items); // ["a", "c", "b", "d"]
remove(items, "x"); // No effect if element not found
console.log(items); // ["a", "c", "b", "d"]
// Function array invocation
const callbacks = [
(msg: string) => console.log(`Callback 1: ${msg}`),
(msg: string) => console.log(`Callback 2: ${msg}`),
(msg: string) => console.log(`Callback 3: ${msg}`)
];
invokeArrayFns(callbacks, "Hello World");
// Logs:
// "Callback 1: Hello World"
// "Callback 2: Hello World"
// "Callback 3: Hello World"
// Empty callback arrays are handled safely
invokeArrayFns([], "message"); // No effect
// Change detection
console.log(hasChanged(1, 1)); // false
console.log(hasChanged(1, 2)); // true
console.log(hasChanged(NaN, NaN)); // false (Object.is handles NaN correctly)
console.log(hasChanged(0, -0)); // true (Object.is distinguishes -0/+0)
console.log(hasChanged(null, undefined)); // true
// Using constants
const defaultConfig = extend({}, EMPTY_OBJ, { theme: "dark" });
console.log(defaultConfig); // { theme: "dark" }
const emptyList = EMPTY_ARR.slice(); // Create new array from empty template
console.log(emptyList); // []
// No-op functions
const cleanup = NOOP; // Safe default cleanup function
const isDisabled = NO; // Function that always returns false
// Property definition with symbols
const secretKey = Symbol("secret");
def(obj, secretKey, "hidden value");
console.log(obj[secretKey]); // "hidden value"
// Number conversion utilities
console.log(looseToNumber("123")); // 123
console.log(looseToNumber("123.45")); // 123.45
console.log(looseToNumber("123-foo")); // 123 (parses what it can)
console.log(looseToNumber("abc")); // "abc" (returns as-is)
console.log(toNumber("123")); // 123
console.log(toNumber("123.45")); // 123.45
console.log(toNumber("123-foo")); // "123-foo" (returns as-is)
console.log(toNumber("abc")); // "abc" (returns as-is)// Safe object merging patterns
function mergeConfig(userConfig: any) {
// Always start with empty object to avoid mutations
return extend({}, defaultConfig, userConfig);
}
// Safe property definition
function defineHiddenProperty(obj: object, key: string, value: any) {
def(obj, key, value, false); // Non-writable by default
}
// Safe array cleanup
function cleanupCallbacks(callbacks: Function[]) {
// Remove all callbacks
callbacks.splice(0, callbacks.length);
}Object.assign - native performanceindexOf + spliceObject.defineProperty with optimized defaultsObject.is which is optimized for equality checkingThese utilities are used throughout Vue's internals:
extend for merging prop defaultsinvokeArrayFns for calling multiple event handlershasChanged for detecting when reactive values changedef for defining non-enumerable properties on reactive objectsInstall with Tessl CLI
npx tessl i tessl/npm-vue--shared