Methods: automatic binding on read?

# Axel Rauschmayer (13 years ago)

I wonder if, with the concise method notation for literals (and possibly class declarations), one couldn’t introduce three modes of accessing a property: Read (getter), write (setter) and call (call interceptor?).

  • Manually assigned functions: everything works as it does now.
  • Concise method notation:
    • Read: bind this
    • Write: apply defineMethod to the argument (not sure about this one)
    • Call: same as before

I have no idea how this would fit into the current semantics, so it might be a silly idea, but it would eliminate a common source of bugs.

# Brendan Eich (13 years ago)

You mean "automatic binding with memoization on read", I hope.

Otherwise you break o.m === o.m.

This can be implemented with accessors and weakmaps, of course. That says two things to me:

  1. It ain't cheap so should not be default, esp. not for method definition shorthand.

  2. We should let the cows make a pavement-worthy path.

# Axel Rauschmayer (13 years ago)

On Apr 13, 2012, at 23:40 , Brendan Eich wrote:

You mean "automatic binding with memoization on read", I hope.

Otherwise you break o.m === o.m.

That makes sense, yes.

This can be implemented with accessors and weakmaps, of course. That says two things to me:

  1. It ain't cheap so should not be default, esp. not for method definition shorthand.

  2. We should let the cows make a pavement-worthy path.

What would be nice to have would be the following (with prettier wrapping):

function myDefineMethod(obj, propName, func) {
    Object.defineProperty(obj, propName, {
        get: function () {
            // TODO: memoization
            return func.bind(this);
        },
        value: func
    });
}

However, you can’t have both a getter and a value for a property. If calling a method was different from reading the property and invoking the returned reference then it could be done. Then we would have:

 someObj.foo    // get
 someObj.foo = bar    // set
 someObj.foo(...)    // invoke

That means the property descriptor would look as follows:

function myDefineMethod(obj, propName, func) {
    Object.defineProperty(obj, propName, {
        get: function () {
            // TODO: memoization
            return func.bind(this);
        },
        invoke: func
    });
}

This might clash with the proxy protocol and might thus not be a good idea.