Skip to content

Commit a272d3b

Browse files
feat(is): add isPlainObject function to check for plain objects
1 parent 3145faf commit a272d3b

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

packages/helpers/src/is.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,14 @@ export const isObject = (value) => value !== null && typeof value === 'object' &
2626
* @returns {boolean} True if the value is undefined, false otherwise.
2727
*/
2828
export const isUndefined = (value) => typeof value === 'undefined';
29+
30+
/**
31+
* Checks if the given value is a plain object (object literal).
32+
* @param {*} obj - The value to check.
33+
* @returns {boolean} True if the value is a plain object, false otherwise.
34+
*/
35+
export const isPlainObject = (obj) => {
36+
if (Object.prototype.toString.call(obj) !== '[object Object]') return false;
37+
const proto = Object.getPrototypeOf(obj);
38+
return proto === null || proto === Object.prototype;
39+
};

packages/helpers/src/is.test.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isArray, isEqual, isObject, isUndefined } from './index.js';
1+
import { isArray, isEqual, isObject, isPlainObject, isUndefined } from './index.js';
22

33
describe('helpers', () => {
44
describe('is', () => {
@@ -60,5 +60,54 @@ describe('helpers', () => {
6060
expect(isUndefined('')).toBe(false);
6161
});
6262
});
63+
64+
describe('isPlainObject', () => {
65+
it('should return true for plain objects', () => {
66+
expect(isPlainObject({})).toBe(true);
67+
expect(isPlainObject({ foo: 'bar' })).toBe(true);
68+
expect(isPlainObject(Object.create(null))).toBe(true);
69+
expect(isPlainObject(Object.create(Object.prototype))).toBe(true);
70+
expect(isPlainObject(Object.assign({}, { a: 1 }))).toBe(true);
71+
});
72+
73+
it('should return false for primitives', () => {
74+
expect(isPlainObject(true)).toBe(false);
75+
expect(isPlainObject(undefined)).toBe(false);
76+
expect(isPlainObject(1)).toBe(false);
77+
expect(isPlainObject('string')).toBe(false);
78+
expect(isPlainObject(Symbol('s'))).toBe(false);
79+
});
80+
81+
it('should return false for `null`', () => {
82+
expect(isPlainObject(null)).toBe(false);
83+
});
84+
85+
it('should return false for functions and instances', () => {
86+
function Foo() {
87+
this.abc = {};
88+
}
89+
90+
expect(isPlainObject(Foo)).toBe(false);
91+
expect(isPlainObject(new Foo())).toBe(false);
92+
expect(isPlainObject(() => {})).toBe(false);
93+
expect(isPlainObject(function () {})).toBe(false);
94+
});
95+
96+
it('should return false for arrays', () => {
97+
expect(isPlainObject([])).toBe(false);
98+
expect(isPlainObject([1, 2, 3])).toBe(false);
99+
});
100+
101+
it('should return false for built-in objects', () => {
102+
expect(isPlainObject(new Date())).toBe(false);
103+
expect(isPlainObject(new Map())).toBe(false);
104+
expect(isPlainObject(new Set())).toBe(false);
105+
expect(isPlainObject(/abc/)).toBe(false);
106+
});
107+
108+
it('should return false for objects created with Object.create and a custom prototype', () => {
109+
expect(isPlainObject(Object.create({}))).toBe(false);
110+
});
111+
});
63112
});
64113
});

0 commit comments

Comments
 (0)