Reputation: 19285
I have a value which may be a primitive or a function or an object containing primitives/functions/objects recursively.
Given a theThis
argument, how can I deep bind all functions which may be inside my value to theThis
?
I tried something like:
function deepBind(o, ths) {
Object.getOwnPropertyNames(o).forEach(key => {
const desc=Object.getOwnPropertyDescriptor(o, key);
if (typeof desc === "function") Object.defineProperty(o, key, key.bind(ths));
if (Object.getOwnPropertyNames(key).length>0) deepBind(o.key, ths);
});
}
but that failed :(
I looked at some solutions like https://github.com/jonschlinkert/deep-bind/blob/master/index.js but that is not standalone.
I am looking for a deepBind(val, theThis)
solution which is standalone.
I need the solution to also cover getters and setters.
Thx!
Upvotes: 2
Views: 683
Reputation: 2032
something along the lines of :
function deepBind (o, thisVal) {
return Object.keys(o)
.reduce((res, key) => {
const v = o[key];
const tv = typeof v;
switch (tv) {
case "object":
// should be updated for arrays...
if ( v !== null ) {
res[key] = deepBind(v, thisVal);
} else {
res[key] = v;
}
break;
case "function":
res[key] = v.bind(thisVal);
break;
default:
res[key] = v;
break;
}
return res;
}, {});
}
It recursively copies values from the original objects, binding functions props to the thisVal
.
Please note that binding recursively does not make a lot of sense because people expect the lexical context to be defined via its call site.
Upvotes: 1
Reputation: 1
This seems to work as you want
function deepBind(o, ths) {
Object.entries(o).forEach(([key, value]) => {
if (typeof value === "function") {
// don't use value here :p
o[key] = o[key].bind(ths);
}
if (typeof value === 'object' || typeof value === 'function') {
deepBind(value, ths);
}
});
}
const v = {
foo:3,
fn: function() {
console.log(this);
},
obj: {
bar: 4,
fn: function() {
console.log(this);
}
}
};
var someThis = {hello: 'world'};
deepBind(v, someThis);
v.fn();
v.obj.fn();
Upvotes: 1