0

If one has an existing object obj:

const obj = {
  i: 0,
  foo(){ 
    console.log(this.i) 
    this.i +=1
  }
}

obj.foo() // => 0

Is it possible to merge a function into it:

// the following function code should be added to `obj`
function obj(){
  this.foo()
}

// after the merge the following should both work:
obj.foo() // => 1
obj() // => 2
TrevTheDev
  • 2,616
  • 2
  • 18
  • 36
  • 1
    The problem isn't merging properties from a function (or any other object) to your original object, it's that objects can't be made callable. You would need some other type of data structure. See [this discussion](https://stackoverflow.com/questions/19335983/can-you-make-an-object-callable). – Zac Anger Jun 15 '23 at 05:06
  • 1
    You can assign all the properties of the object to the function. You’d then also need to bend over backwards a bit more to bind the function to itself so `this` works with just `obj()`. All that seems highly unorthodox though… – deceze Jun 15 '23 at 05:09
  • If anyone stumbles across this: here is the solution that ultimately worked for me: https://www.typescriptlang.org/play?#code/C4TwDgpgBAYg9nAQgQwM7QLxVJOAzKOAIwCsBYAKAEsA7YCAJz2QGNp44oIAPemgE1SwEKdAG9KUKAAoAlAC4AbnCr9KAX0os4NVMEKkoWCRSlV5UAAwAaSVDwI5YqHanbdcADYQAdJ7gA5tLAABZUqD5Usi6mUthhEVRQANQYAIx2mhRZlMQkPg5wclAA9CVGAHxWlFo6evY0RvYArjQswFQ6LW1Odng0BY6yGlBownA1FADypBDtPujAAAoMcMBr4BBTeNL91gYksgDck-2DRdFllVAZFP3FVxhVAEyUZ4UP5U9QAMxvNJ9rgAWShAA – TrevTheDev Jun 16 '23 at 03:12

3 Answers3

1

I am not sure how the obj function is merged into the obj object if you want to call it standalone. However, you could use a bound function instead.

Besides: You cannot have a constant obj and a function obj that share the same name. I therefor changed the function name to fn:

const obj = {
  i: 0,
  foo() {
    console.log(this.i);
    this.i += 1;
  }
};

function fn() {
  this.foo();
}



const bound = fn.bind(obj);



bound();
obj.foo();
bound();

EDIT

Now that I think of it, you don't need the fn function since you can use const bound = obj.foo.bind(obj); and achieve exactly the same:

const obj = {
  i: 0,
  foo() {
    console.log(this.i);
    this.i += 1;
  }
};

const bound = obj.foo.bind(obj);

bound();
obj.foo();
bound();
David
  • 3,552
  • 1
  • 13
  • 24
  • Thank you. This solution doesn't allow one to call `bound.foo()` - so one has two separate objects that need to be passed around, vs. a single integrated object. – TrevTheDev Jun 16 '23 at 02:48
0

You can merge function to object using Object.assign. I changed obj() to baz() to make it more clear.

const obj = {
  i: 0,
  foo() {
    console.log(this.i);
    this.i += 1;
  }
};

function baz() {
  this.foo();
}

Object.assign(obj, { baz });
obj.foo() // => 0
obj.baz() // => 1

However when you call baz(), it will throw error because it doesn't understand the context this in baz(). So you need to call baz() with obj as the context

baz.call(obj); // => 2
Tony
  • 1,106
  • 1
  • 10
  • 17
-1

there are multiple ways to add property to an object like :

1.using dot notation, 
2.using bracket [ ] notation, 
3.using defineProperty(), 
4.using spread operator, 
5.using Object.assign() 

const obj = {
  i: 0,
  foo(){ 
    console.log(this.i) 
    this.i +=1
  }
}

const newObj = {...obj, obj(){console.log("ok")}}
newObj.obj()

obj['bar'] = function(){
    console.log("bar")
}

obj.bar()
Yewin
  • 160
  • 1
  • 7
  • The OP didn't want to know how add a new property to an existing object, he wants a function that, when called without context, behaves as if it is called in the context of the object. – David Jun 15 '23 at 08:30
  • can you edit the question? @David – Yewin Jun 15 '23 at 09:05
  • Errr... why? The OP's description says what he wants to achieve, have a look into the second code block in the question. – David Jun 15 '23 at 09:12