Skip to content

Commit

Permalink
feat: update bind and call
Browse files Browse the repository at this point in the history
  • Loading branch information
seognil committed Mar 12, 2021
1 parent a9462e6 commit ada5c5e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
36 changes: 24 additions & 12 deletions js/reimplement/bind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,60 @@
{
const obj = {
val: 'inner',
fn(...args: any[]) {
fn(...args: unknown[]) {
console.warn(...args, this);
},
};

obj.fn(333);
obj.fn('obj call');

const rawFn = obj.fn;
rawFn(666);
rawFn('raw call');

const bindedFn = obj.fn.bind({ val: 'outer' });
bindedFn(999);
bindedFn('bind1');

const bindedFn2 = bindedFn.bind({ val: 'more' });
bindedFn2(0);
bindedFn2('bind2');
}

console.log('--------');

// * ================================================================================ our

{
const bind = <T, K>(context: any, fn: (...args: T[]) => K) => (...args: T[]) =>
fn.apply(context, args);
const bind = <C, T, K>(context: C, fn: (...args: T[]) => K) => {
const sf = Symbol();

Object.defineProperty(context, sf, {
enumerable: false,
configurable: true,
writable: true,
value: fn,
});

const sc: C & { [sf]?: Function } = context;

return (...args: T[]) => sc[sf]?.(...args) as K;
};

// * ----------------

const obj = {
val: 'inner',
fn(...args: any[]) {
fn(...args: unknown[]) {
console.warn(...args, this);
},
};

obj.fn(333);
obj.fn('obj call');

const rawFn = obj.fn;
rawFn(666);
rawFn('raw call');

const bindedFn = bind({ val: 'outer' }, obj.fn);
bindedFn(999);
bindedFn('bind1');

const bindedFn2 = bind({ val: 'more' }, bindedFn);
bindedFn2(0);
bindedFn2('bind2');
}
19 changes: 9 additions & 10 deletions js/reimplement/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
const obj = {
val: 'inner',
fn(...args: any[]) {
fn(...args: unknown[]) {
console.warn(...args, this);
},
};
Expand All @@ -17,20 +17,19 @@ console.log('--------');
// * ================================================================================ our

{
const call = <T>(context: any, fn: Function, ...args: T[]) => {
let i = 0;
while (context[`__fn${i}`]) i++;
const shallowKey = `__fn${i}`;
const call = <C, T>(context: C, fn: Function, ...args: T[]) => {
const sf = Symbol();

Object.defineProperty(context, shallowKey, {
value: fn,
Object.defineProperty(context, sf, {
enumerable: false,
configurable: true,
writable: true,
value: fn,
});

const result = context[shallowKey](...args);

delete context[shallowKey];
const sc: C & { [sf]?: Function } = context;
const result = sc[sf]?.(...args);
delete sc[sf];

return result;
};
Expand Down

0 comments on commit ada5c5e

Please sign in to comment.