mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-27 14:57:44 +03:00
feat(bind): Move bind to compat
This commit is contained in:
parent
1135f67c06
commit
f6be4d7ad6
@ -122,7 +122,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'noop', link: '/reference/function/noop' },
|
||||
{ text: 'ary', link: '/reference/function/ary' },
|
||||
{ text: 'unary', link: '/reference/function/unary' },
|
||||
{ text: 'bind', link: '/reference/function/bind' },
|
||||
{ text: 'bind (compat)', link: '/reference/compat/function/bind' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -133,6 +133,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'noop', link: '/ko/reference/function/noop' },
|
||||
{ text: 'ary', link: '/reference/function/ary' },
|
||||
{ text: 'unary', link: '/reference/function/unary' },
|
||||
{ text: 'bind (호환성)', link: '/reference/compat/function/unary' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -116,7 +116,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'noop', link: '/zh_hans/reference/function/noop' },
|
||||
{ text: 'ary', link: '/zh_hans/reference/function/ary' },
|
||||
{ text: 'unary', link: '/zh_hans/reference/function/unary' },
|
||||
{ text: 'bind', link: '/zh_hans/reference/function/bind' },
|
||||
{ text: 'bind (兼容性)', link: '/zh_hans/reference/function/bind' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
52
docs/ko/reference/compat/function/bind.md
Normal file
52
docs/ko/reference/compat/function/bind.md
Normal file
@ -0,0 +1,52 @@
|
||||
# bind
|
||||
|
||||
::: info
|
||||
이 함수는 [lodash와 완전히 호환](../../../compatibility.md)돼요. `es-toolkit/compat` 라이브러리에서 쓸 수 있어요.
|
||||
:::
|
||||
|
||||
함수의 `this`를 고정하고, `partialArgs`로 미리 인자를 제공해요.
|
||||
|
||||
Symbol 타입의 `bind.placeholder`를 쓰면, 미리 제공한 인자가 사용될 위치를 결정할 수 있어요.
|
||||
|
||||
내장 `Function#bind` 과는 다르게, 함수의 `length` 프로퍼티는 설정하지 않아요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function bind<F extends Function>(func: F, thisObj?: unknown, ...partialArgs: any[]): F;
|
||||
|
||||
namespace bind {
|
||||
placeholder: symbol;
|
||||
}
|
||||
```
|
||||
|
||||
### 파라미터
|
||||
|
||||
- `func` (`F`): `this` 를 고정할 함수.
|
||||
- `thisObj` (`any`, optional): 함수에 고정될 `this` 객체.
|
||||
- `partialArgs` (`any[]`): 미리 주어질 인자.
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`F`): `this`가 고정된 함수.
|
||||
|
||||
## 예시
|
||||
|
||||
```typescript
|
||||
import { bind } from 'es-toolkit/compat';
|
||||
|
||||
function greet(greeting, punctuation) {
|
||||
return greeting + ' ' + this.user + punctuation;
|
||||
}
|
||||
|
||||
const object = { user: 'fred' };
|
||||
|
||||
let bound = bind(greet, object, 'hi');
|
||||
bound('!');
|
||||
// => 'hi fred!'
|
||||
|
||||
// Bound with placeholders.
|
||||
bound = bind(greet, object, bind.placeholder, '!');
|
||||
bound('hi');
|
||||
// => 'hi fred!'
|
||||
```
|
@ -1,15 +1,20 @@
|
||||
# bind
|
||||
|
||||
Creates a function that invokes `func` with the `this` binding of `thisArg` and `partials` prepended to the arguments it receives.
|
||||
::: info
|
||||
This function is fully compatible with lodash. You can find it in our [compatibility library](../../../compatibility.md), `es-toolkit/compat`.
|
||||
:::
|
||||
|
||||
Creates a function that invokes `func` with the `this` binding of `thisObj` and `partials` prepended to the arguments it receives.
|
||||
|
||||
The `bind.placeholder` value, which defaults to a `symbol`, may be used as a placeholder for partially applied arguments.
|
||||
|
||||
**Note:** Unlike native `Function#bind`, this method doesn't set the `length` property of bound functions.
|
||||
Note that unlike native `Function#bind`, this method doesn't set the `length` property of bound functions.
|
||||
|
||||
## Signature
|
||||
|
||||
```typescript
|
||||
function bind(func: (...args: any[]) => any, thisArg?: any, ...partials: any[]): (...args: any[]) => any;
|
||||
function bind<F extends Function>(func: F, thisObj?: unknown, ...partialArgs: any[]): F;
|
||||
|
||||
namespace bind {
|
||||
placeholder: symbol;
|
||||
}
|
||||
@ -17,18 +22,18 @@ namespace bind {
|
||||
|
||||
### Parameters
|
||||
|
||||
- `fn` (`(...args: any[]) => any`): The function to bind.
|
||||
- `thisArg` (`any`, optional): The `this` binding of `func`.
|
||||
- `partials` (`any[]`): The arguments to be partially applied.
|
||||
- `func` (`F`): The function to bind.
|
||||
- `thisObj` (`any`, optional): The `this` binding of `func`.
|
||||
- `partialArgs` (`any[]`): The arguments to be partially applied.
|
||||
|
||||
### Returns
|
||||
|
||||
(`(...args: any[]) => any`): Returns the new bound function.
|
||||
(`F`): Returns the new bound function.
|
||||
|
||||
## Examples
|
||||
|
||||
```typescript
|
||||
import { bind } from 'es-toolkit/function';
|
||||
import { bind } from 'es-toolkit/compat';
|
||||
|
||||
function greet(greeting, punctuation) {
|
||||
return greeting + ' ' + this.user + punctuation;
|
@ -1,5 +1,10 @@
|
||||
# bind
|
||||
|
||||
::: info
|
||||
此函数与 lodash 完全兼容。您可以在我们的[兼容性库](../../../compatibility.md)中找到它,`es-toolkit/compat`。
|
||||
:::
|
||||
|
||||
|
||||
创建一个调用 `func` 的函数,`thisArg` 绑定 `func` 函数中的 `this`,并且 `func` 函数会接收 `partials` 附加参数。
|
||||
|
||||
`bind.placeholder` 的值默认是一个 `symbol`,可以用作附加的部分参数的占位符。
|
||||
@ -28,7 +33,7 @@ namespace bind {
|
||||
## 示例
|
||||
|
||||
```typescript
|
||||
import { bind } from 'es-toolkit/function';
|
||||
import { bind } from 'es-toolkit/compat';
|
||||
|
||||
function greet(greeting, punctuation) {
|
||||
return greeting + ' ' + this.user + punctuation;
|
@ -1,8 +1,8 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { bind } from './bind';
|
||||
import { isEqual } from '../predicate';
|
||||
import { isEqual } from '../../predicate/isEqual';
|
||||
|
||||
function fn(this: any) {
|
||||
function fn(this: any, ..._: any[]) {
|
||||
const result = [this];
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
return result.concat(Array.from(arguments));
|
||||
@ -79,7 +79,7 @@ describe('bind', () => {
|
||||
|
||||
it('should create a function with a `length` of `0`', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const fn = function (_a: unknown, _b: unknown, _c: unknown) {};
|
||||
const fn = function (_a: unknown, _b: unknown, _c: unknown) { };
|
||||
let bound = bind(fn, {});
|
||||
|
||||
expect(bound.length).toBe(0);
|
||||
@ -107,7 +107,7 @@ describe('bind', () => {
|
||||
return this;
|
||||
}
|
||||
|
||||
function Bar() {}
|
||||
function Bar() { }
|
||||
|
||||
const thisArg = { a: 1 };
|
||||
const boundFoo = bind(Foo, thisArg) as any;
|
||||
@ -173,7 +173,7 @@ describe('bind', () => {
|
||||
|
||||
it('should not error when calling bound class constructors with the `new` operator', () => {
|
||||
const createCtor: any = function () {
|
||||
return class A {};
|
||||
return class A { };
|
||||
};
|
||||
|
||||
const bound = bind(createCtor()) as any;
|
60
src/compat/function/bind.ts
Normal file
60
src/compat/function/bind.ts
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Creates a function that invokes `func` with the `this` binding of `thisArg` and `partials` prepended to the arguments it receives.
|
||||
*
|
||||
* The `bind.placeholder` value, which defaults to a `symbol`, may be used as a placeholder for partially applied arguments.
|
||||
*
|
||||
* Note: Unlike native `Function#bind`, this method doesn't set the `length` property of bound functions.
|
||||
*
|
||||
* @param {(...args: any[]) => any} func The function to bind.
|
||||
* @param {any} thisArg The `this` binding of `func`.
|
||||
* @param {any[]} partials The arguments to be partially applied.
|
||||
* @returns {(...args: any[]) => any} Returns the new bound function.
|
||||
*
|
||||
* @example
|
||||
* function greet(greeting, punctuation) {
|
||||
* return greeting + ' ' + this.user + punctuation;
|
||||
* }
|
||||
* const object = { user: 'fred' };
|
||||
* let bound = bind(greet, object, 'hi');
|
||||
* bound('!');
|
||||
* // => 'hi fred!'
|
||||
*
|
||||
* bound = bind(greet, object, bind.placeholder, '!');
|
||||
* bound('hi');
|
||||
* // => 'hi fred!'
|
||||
*/
|
||||
export function bind<F extends Function>(func: F, thisObj?: unknown, ...partialArgs: any[]): F {
|
||||
const binded = function (this: any, ...providedArgs: any[]) {
|
||||
const args: any[] = [];
|
||||
|
||||
// Populate args by merging partialArgs and providedArgs.
|
||||
// e.g.. when we call bind(func, {}, [1, bind.placeholder, 3])(2, 4);
|
||||
// we have args with [1, 2, 3, 4].
|
||||
let startIndex = 0;
|
||||
|
||||
for (let i = 0; i < partialArgs.length; i++) {
|
||||
const arg = partialArgs[i];
|
||||
|
||||
if (arg === bind.placeholder) {
|
||||
args.push(providedArgs[startIndex++]);
|
||||
} else {
|
||||
args.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = startIndex; i < providedArgs.length; i++) {
|
||||
args.push(providedArgs[i]);
|
||||
}
|
||||
|
||||
if (this instanceof binded) {
|
||||
// @ts-expect-error - fn is a constructor
|
||||
return new func(...args);
|
||||
}
|
||||
|
||||
return func.apply(thisObj, args);
|
||||
};
|
||||
|
||||
return binded as any as F;
|
||||
}
|
||||
|
||||
bind.placeholder = Symbol('bind.placeholder');
|
@ -35,6 +35,7 @@ export { zipObjectDeep } from './array/zipObjectDeep.ts';
|
||||
export { head as first } from '../array/head.ts';
|
||||
|
||||
export { ary } from './function/ary.ts';
|
||||
export { bind } from './function/bind.ts';
|
||||
|
||||
export { get } from './object/get.ts';
|
||||
export { set } from './object/set.ts';
|
||||
|
@ -1,48 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Creates a function that invokes `func` with the `this` binding of `thisArg` and `partials` prepended to the arguments it receives.
|
||||
*
|
||||
* The `bind.placeholder` value, which defaults to a `symbol`, may be used as a placeholder for partially applied arguments.
|
||||
*
|
||||
* **Note:** Unlike native `Function#bind`, this method doesn't set the `length` property of bound functions.
|
||||
*
|
||||
* @param {(...args: any[]) => any} func The function to bind.
|
||||
* @param {any} thisArg The `this` binding of `func`.
|
||||
* @param {any[]} partials The arguments to be partially applied.
|
||||
* @returns {(...args: any[]) => any} Returns the new bound function.
|
||||
*
|
||||
* @example
|
||||
* function greet(greeting, punctuation) {
|
||||
* return greeting + ' ' + this.user + punctuation;
|
||||
* }
|
||||
* const object = { user: 'fred' };
|
||||
* let bound = bind(greet, object, 'hi');
|
||||
* bound('!');
|
||||
* // => 'hi fred!'
|
||||
*
|
||||
* bound = bind(greet, object, bind.placeholder, '!');
|
||||
* bound('hi');
|
||||
* // => 'hi fred!'
|
||||
*/
|
||||
export function bind(func: (...args: any[]) => any, thisArg?: any, ...partials: any[]): (...args: any[]) => any {
|
||||
const wrapper = function (this: any, ...args: any[]) {
|
||||
let index = 0;
|
||||
const result = partials.map(bindArg => {
|
||||
if (bindArg === bind.placeholder) {
|
||||
return args[index++];
|
||||
}
|
||||
return bindArg;
|
||||
});
|
||||
for (let i = index; i < args.length; i++) {
|
||||
result.push(args[i]);
|
||||
}
|
||||
if (this instanceof wrapper) {
|
||||
// @ts-expect-error - fn is a constructor
|
||||
return new func(...result);
|
||||
}
|
||||
return func.apply(thisArg, result);
|
||||
};
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
bind.placeholder = Symbol('bind.placeholder') as symbol;
|
@ -7,4 +7,3 @@ export { throttle } from './throttle.ts';
|
||||
export { negate } from './negate.ts';
|
||||
export { ary } from './ary.ts';
|
||||
export { unary } from './unary.ts';
|
||||
export { bind } from './bind.ts';
|
||||
|
Loading…
Reference in New Issue
Block a user