Write a function that checks if a given value is an instance of a given class or superclass. For this problem, an object is considered an instance of a given class if that object has access to that class's methods.
There are no constraints on the data types that can be passed to the function. For example, the value or the class could be undefined
.
Example 1:
Input: func = () => checkIfInstanceOf(new Date(), Date)
Output: true
Explanation: The object returned by the Date constructor is, by definition, an instance of Date.
Example 2:
Input: func = () => { class Animal {}; class Dog extends Animal {}; return checkIfInstanceOf(new Dog(), Animal); }
Output: true
Explanation:
class Animal {};
class Dog extends Animal {};
checkIfInstanceOf(new Dog(), Animal); // true
Dog is a subclass of Animal. Therefore, a Dog object is an instance of both Dog and Animal.
Example 3:
Input: func = () => checkIfInstanceOf(Date, Date)
Output: false
Explanation: A date constructor cannot logically be an instance of itself.
Example 4:
Input: func = () => checkIfInstanceOf(5, Number)
Output: true
Explanation: 5 is a Number. Note that the "instanceof" keyword would return false. However, it is still considered an instance of Number because it accesses the Number methods. For example "toFixed()".
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method involves exhaustively checking whether an object is an instance of a given class. We explore all possibilities by comparing the object's type against the class and its inheritance hierarchy. This ensures we leave no stone unturned in our verification process.
Here's how the algorithm would work step-by-step:
def is_object_instance_of_class(object_to_check, class_to_check):
# Directly check if the object is of the specified class.
if type(object_to_check) is class_to_check:
return True
object_class = type(object_to_check)
# Iterate through the base classes to check inheritance.
for base_class in object_class.__bases__:
# Recursively check parent classes for the specified class
if base_class is class_to_check:
return True
# Check the base class's inheritance
if is_object_instance_of_class(base_class, class_to_check):
return True
# If none of the base classes match, return False.
return False
To determine if something belongs to a specific type, we avoid complicated checks. The most efficient way is to ask directly if the thing 'is' the type we're interested in, using the language's built-in tool for this purpose. This avoids manual comparisons or guesswork.
Here's how the algorithm would work step-by-step:
def is_object_instance_of_class(object_to_check, class_to_check):
# Check if the object is an instance of the given class.
if isinstance(object_to_check, class_to_check):
# The object is an instance of the class.
is_instance = True
else:
# The object is not an instance of the class.
is_instance = False
# Return whether the object is an instance of the class.
return is_instance
def is_object_instance_of_class_alt(object_to_check, class_to_check):
# Directly using 'isinstance' is the most pythonic approach.
return isinstance(object_to_check, class_to_check)
Case | How to Handle |
---|---|
Null or undefined object | Return false immediately if the object is null or undefined to avoid errors. |
Null or undefined class | Return false immediately if the class is null or undefined to prevent issues. |
Object is created from a different context (e.g., different iframe) | Check the object's constructor and prototype chain carefully, as cross-context instances can cause unexpected behavior. |
Class is a primitive type (e.g., Number, String, Boolean) | Return false; primitive types should not be considered classes in this context. |
Inheritance chains – object is an instance of a superclass | Recursively traverse the prototype chain of the object to check against all superclasses. |
Object has a modified prototype chain | Ensure that prototype checks are robust against prototype pollution attacks or intentional prototype modifications. |
The class has a custom `[Symbol.hasInstance]` method | Respect the class's `[Symbol.hasInstance]` method if present, as it overrides the default behavior. |
Class is an abstract class or interface | Determine if the intended behavior should treat instances of concrete subclasses as instances of the abstract class/interface. |