用js实现typeof的功能
function myTypeOf(value) {
// Handle null specially as typeof null === 'object' which is incorrect.
if (value === null) {
return "null";
}
// Use the built-in typeof for most cases.
const type = typeof value;
// Further refine the 'object' type.
if (type === 'object') {
// Check for arrays.
if (Array.isArray(value)) {
return 'array';
}
// Check for functions (using Object.prototype.toString is more robust than instanceof Function)
if (Object.prototype.toString.call(value) === '[object Function]') {
return 'function';
}
// Check for dates
if (value instanceof Date) {
return 'date';
}
// Check for RegExps
if (value instanceof RegExp) {
return 'regexp';
}
// Other objects remain as 'object'
return 'object';
}
// For all other types, return the result of the built-in typeof.
return type;
}
// Test cases
console.log(myTypeOf(null)); // null
console.log(myTypeOf(undefined)); // undefined
console.log(myTypeOf("hello")); // string
console.log(myTypeOf(123)); // number
console.log(myTypeOf(true)); // boolean
console.log(myTypeOf({})); // object
console.log(myTypeOf([])); // array
console.log(myTypeOf(function() {})); // function
console.log(myTypeOf(new Date())); // date
console.log(myTypeOf(/regex/)); // regexp
console.log(myTypeOf(Symbol())); // symbol
console.log(myTypeOf(BigInt(123))); // bigint
Explanation and Key Improvements:
- Handles
null
correctly:typeof null
returns "object", which is a historical JavaScript quirk. This implementation explicitly checks fornull
and returns "null". - Distinguishes Arrays: Uses
Array.isArray(value)
which is the most reliable way to detect arrays, including those created in different frames/iframes. - Robust Function Detection: Uses
Object.prototype.toString.call(value) === '[object Function]'
which is a more robust way to detect functions compared tovalue instanceof Function
, especially in scenarios involving iframes or different execution contexts. - Detects Dates and RegExps: Includes checks for
Date
andRegExp
objects usinginstanceof
. - Handles other primitives correctly: For other primitive types (string, number, boolean, symbol, bigint, undefined), it relies on the built-in
typeof
operator.
This improved version provides a more accurate and comprehensive implementation of typeof
functionality, addressing common edge cases and providing more specific type information for complex objects. It's generally a good practice to use these more robust checks when you need to determine the exact type of a value in JavaScript.