feat(compat): implement toPlainObject (#879)
Some checks failed
CI / codecov (push) Has been cancelled
Release / release (push) Has been cancelled

* feat(compat): implement toPlainObject

* chore: make lint happy
This commit is contained in:
D-Sketon 2024-12-08 20:37:16 +08:00 committed by GitHub
parent 99f7611e4b
commit 622102c9a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 225 additions and 0 deletions

View File

@ -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);
});
});

View File

@ -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<string, any>;
```
### パラメータ
- `value` (`any`): 変換する値です。
### 戻り値
(`Record<string, any>`): 変換されたオブジェクトを返します。
## 例
```typescript
function Foo() {
this.b = 2;
}
Foo.prototype.c = 3;
toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 }
```

View File

@ -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<string, any>;
```
### 파라미터
- `value` (`any`): 변환할 값이에요.
### 반환 값
(`Record<string, any>`): 변환된 객체를 반환해요.
## 예시
```typescript
function Foo() {
this.b = 2;
}
Foo.prototype.c = 3;
toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 }
```

View File

@ -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 isnt 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<string, any>;
```
### Parameters
- `value` (`any`): The value to convert.
### Returns
(`Record<string, any>`): Returns the converted plain object.
## Examples
```typescript
function Foo() {
this.b = 2;
}
Foo.prototype.c = 3;
toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 }
```

View File

@ -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<string, any>;
```
### 参数
- `value` (`any`): 要转换的值。
### 返回值
(`Record<string, any>`): 返回转换后的普通对象。
## 示例
```typescript
function Foo() {
this.b = 2;
}
Foo.prototype.c = 3;
toPlainObject(new Foo()); // => { 'b': 2, 'c': 3 }
```

View File

@ -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';

View File

@ -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);
});
});

View File

@ -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<string, any>} 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<string, any> {
const plainObject: Record<string, any> = {};
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;
}