diff --git a/benchmarks/performance/toPlainObject.bench.ts b/benchmarks/performance/toPlainObject.bench.ts new file mode 100644 index 000000000..233a30362 --- /dev/null +++ b/benchmarks/performance/toPlainObject.bench.ts @@ -0,0 +1,23 @@ +import { bench, describe } from 'vitest'; +import { toPlainObject as toPlainObjectCompatToolkit_ } from 'es-toolkit/compat'; +import { toPlainObject as toPlainObjectLodash_ } from 'lodash'; + +const toPlainObjectCompatToolkit = toPlainObjectCompatToolkit_; +const toPlainObjectLodash = toPlainObjectLodash_; + +describe('toPlainObject', () => { + function Foo() { + this.b = 2; + } + + Foo.prototype.c = 3; + const foo = new Foo(); + + bench('es-toolkit/compat/toPlainObject', () => { + toPlainObjectCompatToolkit(foo); + }); + + bench('lodash/toPlainObject', () => { + toPlainObjectLodash(foo); + }); +}); diff --git a/docs/ja/reference/compat/util/toPlainObject.md b/docs/ja/reference/compat/util/toPlainObject.md new file mode 100644 index 000000000..94447ea4c --- /dev/null +++ b/docs/ja/reference/compat/util/toPlainObject.md @@ -0,0 +1,34 @@ +# toPlainObject + +::: info +この関数は互換性のために `es-toolkit/compat` からのみインポートできます。代替可能なネイティブ JavaScript API があるか、まだ十分に最適化されていないためです。 + +`es-toolkit/compat` からこの関数をインポートすると、[lodash と完全に同じように動作](../../../compatibility.md)します。 +::: + +`value`を普通のオブジェクトに変換します。`value`の継承された列挙可能な文字列キー属性を普通のオブジェクトの自身の属性に平坦化します。 + +## インターフェース + +```typescript +function toPlainObject(value: any): Record; +``` + +### パラメータ + +- `value` (`any`): 変換する値です。 + +### 戻り値 + +(`Record`): 変換されたオブジェクトを返します。 + +## 例 + +```typescript +function Foo() { + this.b = 2; +} +Foo.prototype.c = 3; + +toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 } +``` diff --git a/docs/ko/reference/compat/util/toPlainObject.md b/docs/ko/reference/compat/util/toPlainObject.md new file mode 100644 index 000000000..60d0fc72c --- /dev/null +++ b/docs/ko/reference/compat/util/toPlainObject.md @@ -0,0 +1,34 @@ +# toPlainObject + +::: info +이 함수는 호환성을 위한 `es-toolkit/compat` 에서만 가져올 수 있어요. 대체할 수 있는 네이티브 JavaScript API가 있거나, 아직 충분히 최적화되지 않았기 때문이에요. + +`es-toolkit/compat`에서 이 함수를 가져오면, [lodash와 완전히 똑같이 동작](../../../compatibility.md)해요. +::: + +`value`를 일반 객체로 변환해요. `value`의 상속된 열거 가능한 문자열 키 속성을 일반 객체의 속성으로 평평하게 만들어요. + +## 인터페이스 + +```typescript +function toPlainObject(value: any): Record; +``` + +### 파라미터 + +- `value` (`any`): 변환할 값이에요. + +### 반환 값 + +(`Record`): 변환된 객체를 반환해요. + +## 예시 + +```typescript +function Foo() { + this.b = 2; +} +Foo.prototype.c = 3; + +toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 } +``` diff --git a/docs/reference/compat/util/toPlainObject.md b/docs/reference/compat/util/toPlainObject.md new file mode 100644 index 000000000..efe04dc12 --- /dev/null +++ b/docs/reference/compat/util/toPlainObject.md @@ -0,0 +1,34 @@ +# toPlainObject + +::: info +This function is only available in `es-toolkit/compat` for compatibility reasons. It either has alternative native JavaScript APIs or isn’t fully optimized yet. + +When imported from `es-toolkit/compat`, it behaves exactly like lodash and provides the same functionalities, as detailed [here](../../../compatibility.md). +::: + +Converts value to a plain object flattening inherited enumerable string keyed properties of value to own properties of the plain object. + +## Signature + +```typescript +function toPlainObject(value: any): Record; +``` + +### Parameters + +- `value` (`any`): The value to convert. + +### Returns + +(`Record`): Returns the converted plain object. + +## Examples + +```typescript +function Foo() { + this.b = 2; +} +Foo.prototype.c = 3; + +toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 } +``` diff --git a/docs/zh_hans/reference/compat/util/toPlainObjct.md b/docs/zh_hans/reference/compat/util/toPlainObjct.md new file mode 100644 index 000000000..6522ea900 --- /dev/null +++ b/docs/zh_hans/reference/compat/util/toPlainObjct.md @@ -0,0 +1,34 @@ +# toPlainObject + +::: info +出于兼容性原因,此函数仅在 `es-toolkit/compat` 中提供。它可能具有替代的原生 JavaScript API,或者尚未完全优化。 + +从 `es-toolkit/compat` 导入时,它的行为与 lodash 完全一致,并提供相同的功能,详情请见 [这里](../../../compatibility.md)。 +::: + +将 `value` 转换为一个普通对象,将 `value` 的继承的可枚举字符串键属性展平到普通对象的自有属性中。 + +## 签名 + +```typescript +function toPlainObject(value: any): Record; +``` + +### 参数 + +- `value` (`any`): 要转换的值。 + +### 返回值 + +(`Record`): 返回转换后的普通对象。 + +## 示例 + +```typescript +function Foo() { + this.b = 2; +} +Foo.prototype.c = 3; + +toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 } +``` diff --git a/src/compat/index.ts b/src/compat/index.ts index 5a943aef8..703cffdb9 100644 --- a/src/compat/index.ts +++ b/src/compat/index.ts @@ -218,5 +218,6 @@ export { toInteger } from './util/toInteger.ts'; export { toLength } from './util/toLength.ts'; export { toNumber } from './util/toNumber.ts'; export { toPath } from './util/toPath.ts'; +export { toPlainObject } from './util/toPlainObject.ts'; export { toSafeInteger } from './util/toSafeInteger.ts'; export { toString } from './util/toString.ts'; diff --git a/src/compat/util/toPlainObject.spec.ts b/src/compat/util/toPlainObject.spec.ts new file mode 100644 index 000000000..a450ad2c2 --- /dev/null +++ b/src/compat/util/toPlainObject.spec.ts @@ -0,0 +1,30 @@ +import { describe, expect, it } from 'vitest'; +import { toPlainObject } from './toPlainObject'; +import { args } from '../_internal/args'; + +describe('toPlainObject', () => { + it('should flatten inherited string keyed properties', () => { + function Foo(this: any) { + this.b = 2; + } + Foo.prototype.c = 3; + + // @ts-expect-error - Foo is a constructor + const actual = Object.assign({ a: 1 }, toPlainObject(new Foo())); + expect(actual).toEqual({ a: 1, b: 2, c: 3 }); + }); + + it('should convert `arguments` objects to plain objects', () => { + const actual = toPlainObject(args); + const expected = { 0: 1, 1: 2, 2: 3 }; + + expect(actual).toEqual(expected); + }); + + it('should convert arrays to plain objects', () => { + const actual = toPlainObject(['a', 'b', 'c']); + const expected = { 0: 'a', 1: 'b', 2: 'c' }; + + expect(actual).toEqual(expected); + }); +}); diff --git a/src/compat/util/toPlainObject.ts b/src/compat/util/toPlainObject.ts new file mode 100644 index 000000000..5984e74f5 --- /dev/null +++ b/src/compat/util/toPlainObject.ts @@ -0,0 +1,35 @@ +import { keysIn } from '../object/keysIn.ts'; + +/** + * Converts value to a plain object flattening inherited enumerable string keyed properties of value to own properties of the plain object. + * + * @param {any} value The value to convert. + * @returns {Record} Returns the converted plain object. + * + * @example + * function Foo() { + * this.b = 2; + * } + * Foo.prototype.c = 3; + * toPlainObject(new Foo()); // { b: 2, c: 3 } + */ +export function toPlainObject(value: any): Record { + const plainObject: Record = {}; + const valueKeys = keysIn(value); + + for (let i = 0; i < valueKeys.length; i++) { + const key = valueKeys[i]; + const objValue = (value as any)[key]; + if (key === '__proto__') { + Object.defineProperty(plainObject, key, { + configurable: true, + enumerable: true, + value: objValue, + writable: true, + }); + } else { + plainObject[key] = objValue; + } + } + return plainObject; +}