1

I'm trying to bind the this keyword of a function and use the Function as with object dot notation (as Functions are also objects). I figured out using the object literal 'get' to do something like: myFunction.whatever (instead of myFunction().whatever).

Code is:

let template = {name: "William"};
let aux = function(){}
callTo = aux.bind(template);

Object.defineProperty(callTo.prototype, "scream", {
    get: function() {
        console.log(this);
        return "Hi, " + this.name;
    }
});
myObj = new callTo();
myObj.scream;

This causes the: "Object.defineProperty called on non-object" error However, if I bind in each property defined with "get" it will correctly work.

let template = {name: "William"};
let callTo = function(){}

Object.defineProperty(callTo.prototype, "scream", {
    get: function() {
        console.log(this);
        return "Hi, " + this.name;
    }.bind(template)
});
myObj = new callTo();
myObj.scream;  // Outputs Hi William

The working approach works but obligues me to add a bind() at the end of each propery. So question is:

¿Why is first code failing?

Barleby
  • 618
  • 2
  • 9
  • 20
  • `callTo.prototype` is `undefined`. I'm not even sure why you'd attempt to change it here, though - seems like [an XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – VLAZ Feb 03 '22 at 15:31
  • Wait, why would you add properties to the prototype *and bind them*? If you just want methods that have immutable `this`, there are other approaches. – VLAZ Feb 03 '22 at 15:32
  • Reviewing the code again, I'm not even sure what the intention here is. – VLAZ Feb 03 '22 at 15:34
  • @VLAZ I used prototype here because I borrowed that approach from someone else's code, while I was experimenting with defineProperty in conjuntion with getters to call a function without the parenthesis. Originally (before using defineProperty) I had a reveal-pattern code: `callTo = function() { return {scream: this.xxxxx}}.bind(template)`, but that made me access 'scream' as callTo().scream (notice parenthesis) – Barleby Feb 04 '22 at 09:33
  • 1
    `callTo = (function() { return {scream: this.xxxxx}}.bind(template))()` would allow you to do `callTo.scream` if that's what you wish. Although if you need this multiple times I'd probably do something more like `makeCall = function(template) { return { scream: template.xxxx } }` and then you'd reuse it as `callTo = makeCall(template)`. With a module pattern you can also declare `self = template` and use `self` (or whatever name you choose) instead of `this` in methods. I don't see *what* you're trying to accomplish here. It seems like the Y is too complex but I don't know what the X is. – VLAZ Feb 04 '22 at 09:43

0 Answers0