From 53c59b0aedfda3f686154e9c35cb8717225a10a1 Mon Sep 17 00:00:00 2001 From: Andrea Giammarchi Date: Mon, 25 May 2020 17:32:21 +0200 Subject: [PATCH] Avoid unnecesary prototype loop ## Background People at redux-toolkit copy/pasted this utility in there, and [they are not welcoming a PR](https://github.com/reduxjs/redux-toolkit/pull/581) because of that, but the `while` loop in here is completely unnecessary, as the comparison is made on the first `proto` only. ## Improvements * _O(1)_ instead of _O(n)_ * safe fallback for `Object.create(null)` cases * fast lane for `new Class()` derived objects * better performance * smaller code size As this change has zero downsides, unless I am missing some explicit reason to `while` loop instead of never using `getPrototypeOf` more than twice, I hope it'll get in, so that others might copy and paste this new version. Best Regards. --- src/utils/isPlainObject.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/utils/isPlainObject.ts b/src/utils/isPlainObject.ts index 9d1956328a..fc7ac3ab5e 100644 --- a/src/utils/isPlainObject.ts +++ b/src/utils/isPlainObject.ts @@ -3,12 +3,9 @@ * @returns True if the argument appears to be a plain object. */ export default function isPlainObject(obj: any): boolean { - if (typeof obj !== 'object' || obj === null) return false - - let proto = obj - while (Object.getPrototypeOf(proto) !== null) { - proto = Object.getPrototypeOf(proto) - } - - return Object.getPrototypeOf(obj) === proto + return ( + typeof value === 'object' && + value !== null && + Object.getPrototypeOf(Object.getPrototypeOf(value) || {}) === null + ) }