19

Considering the following javascript example:

var myobj = {   func1: function() { alert(name in this) },
                func2: function() { alert(name in this) },
                func3: function() { alert(name in this) }
}

myobj.func2(); // returns true
myobj.func4(); // undefined function

Is it possible to create a 'catch-all' key for myobj that will get called if there is no key/function defined (as in func4()) while retaining the myobj.functionCall() format?

user113716
  • 318,772
  • 63
  • 451
  • 440
  • Really? Care to point to one? If you can find one, I'll delete the question. – user113716 Mar 01 '10 at 17:18
  • @Pointy - are you saying that you can't imagine how it could be implemented in the language? If so, how about a wildcard key like * ? – user113716 Mar 01 '10 at 17:20
  • I'm saying that I'm too dumb to imagine how it'd be implemented :-) Also, the semantics seem like they'd be complicated; would you just get one wildcard entry? What if you set its value to the number 37 instead of a function? – Pointy Mar 01 '10 at 17:23
  • @patrick: there was a question very much like yours last week... can't find it though... – jldupont Mar 01 '10 at 17:24
  • Found it, placed it as answer =) – Joel A. Villarreal Bertoldi Mar 01 '10 at 17:26
  • @jidupont - I've found similar questions that offer workarounds that change the format of the function call. That's no problem. This question is more about whether or not a feature exists in the language to either provide a catch-all or wildcard key, or whether there's some tricky way to accomplish the same effect. – user113716 Mar 01 '10 at 17:27
  • 1
    @Pointy - Keys are unique, therefore only one wildcard would be allowed (in my imaginary world). If it didn't contain a function, you would presumably get the same result as you would if you tried to call a function against any other key that doesn't contain one. – user113716 Mar 01 '10 at 17:46
  • Yes I guess that'd work. Something seems a little kludgey about it, but whatever; it's Javascript, after all :-) – Pointy Mar 01 '10 at 18:15
  • @Pointy - **but whatever; it's Javascript, after all :-) ** How true! :o) – user113716 Mar 01 '10 at 18:45

2 Answers2

39

You can create a JavaScript object with 'wildcard' or 'catch-all' keys using a Proxy and a getter function. Unlike the solutions provided, a Proxy should work in just about any environment, including Node.js

var foo = new Object()

var specialFoo = new Proxy(foo, {
    get(target,name) {
        // do something here
        return name
    }
})

console.log(specialFoo.blabla) // this will output "blabla"

If you want the properties to be callable, simply return a function:

var specialFoo = new Proxy(foo, {
    get(target,name) {
        return function() {
            console.log('derp')
            return name
        }
    }
})


specialFoo.callMe() // this will print derp

Details: documentation on mozilla

zypA13510
  • 1,092
  • 1
  • 10
  • 28
Jochem Stoel
  • 1,371
  • 1
  • 13
  • 23
  • "about any environment", but not IE :( – Christian Apr 11 '18 at 11:56
  • @Christian You can use a polyfill for proxies in IE. Just include if needed. See more information here: https://github.com/GoogleChrome/proxy-polyfill – Jochem Stoel Apr 12 '18 at 17:28
  • At least that polyfill does not support the use case: "This means that the properties you want to proxy must be known at creation time." – Christian Apr 13 '18 at 06:51
  • @Christian Hmm. Really? There is no way to implement a catch all proxy working on IE at all, period? Not on any version? Other polyfills maybe? I would like to know this for sure. Can you confirm? – Jochem Stoel Apr 14 '18 at 11:30
  • Well, that cite was from the link you provided. I don't know if it would be possible to create another polyfill... at least I have not found one which can do it. – Christian Apr 14 '18 at 16:48
  • take a look at https://github.com/krzkaczor/babel-plugin-proxy/blob/master/src/runtime.js – Bernardo Dal Corno Jun 27 '18 at 14:07
  • Maybe that'd be worth a try, but it's documentation states "It is not suitable for production environments because performance impact is huge." – Christian Aug 10 '18 at 09:06
15

You're looking for __noSuchMethod__:
JavaScript getter for all properties

Community
  • 1
  • 1