-
Notifications
You must be signed in to change notification settings - Fork 337
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(compat): implement toPlainObject (#879)
* feat(compat): implement toPlainObject * chore: make lint happy
- Loading branch information
Showing
8 changed files
with
225 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<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 } | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |