Reputation: 1570
Given some basic class, such as a logical predicate class here:
const isACat = new Predicate(obj => obj.cat === true);
Is there a way to determine/trap/identify (perhaps via Reflection
?) the context under which isACat
is being "invoked/evaluated"? By "invoke/evaluate"--because I can't really think of a better word to use right now--I mean something like this:
console.log(isACat(object1)); // being "invoked/evaluated" as a function
console.log(isACat); // being "invoked/evaluated" as a non-function
I specifically mean this in the "runtime" sense, not in the typeof/instanceof
sense.
For the ultimate goal of performing contingent behavior, such as (perhaps via a Proxy
) returning a default function if that instance is being "invoked/evaluated" as a function.
Edit: Maybe in more precise terms, is there such a thing as a "default getter" when no further child prop is passed (i.e. isACat
, but not isACat[ prop ]
)?
Upvotes: 0
Views: 76
Reputation: 2444
I am not seriously suggesting that you do any of the things presented bellow and you will spot their limitation immediately but I thought it was kind of fun to demonstrate.
[{dog: true}, {cat: true}].filter(isACat);// (referenced(), [{cat: true}])
isACat({dog: true}); // (referenced(), false)
let lives = 0;
lives += isACat; // (referenced(), 7)
`Felix ${isACat}` // (referenced(), "Felix is a cat")
The above requires the following, which you could probably generate with a Babel plugin or something (I mean: don't, obviously)
const referenced = (obj) => () => {
console.log(obj, 'was referenced');
return obj;
}
const _isACat = obj => obj.cat === true;
Object.defineProperty(_isACat, 'toString', {
value: () => 'is a cat'
});
Object.defineProperty(_isACat, 'valueOf', {
value: () => 7
});
Object.defineProperty(window, 'isACat', {
get: referenced(_isACat)
});
I don't know what I like the most about it: deceiving expectations thanks to getters, magical type coercion, or local variables leaking to the global scope. It is pure poetry.
More seriously, I don't think Javascript is the language for this but if for some reason you need meta-programming power, maybe give Clojure a go. You can also use macros with ClojureScript, which compiles to Javascript and has Javascript interop, but there is a runtime/compile time distinction which will limit what you can do.
Upvotes: 1
Reputation: 664797
No, there is no such thing. You're just accessing a variable, or whatever the reference to your object is stored in, and you get back a reference value. The object itself has no say about this process - it isn't even looked at yet. This is not "invocation" or "evaluation".
Really, if you need something like this, make the invocation explicit, and write isACat()
(vs isACat(object)
vs isACat.prop()
).
Upvotes: 0