0

Apologies if this is a bit of a weird one...

I have a program written in Java which utilises the ScriptEngine to process user provided JavaScript to extend my application. However, this specific question is related to general JavaScript as opposed to Java or it's ScriptEngine, but I am just explaining this to set the context.

I have a function which returns a string when called - let's call it a() as defined below:

var a = function() {
  return "this is a";
};

When the user calls this function using a() it works fine and outputs "this is a". However, if the user forgets to include the parenthesis then it outputs my actual function definition - expecting this as I am no longer calling the function.

To catch this I have redefined the toString method of my Object to the following:

a.toString = function() {
  return a();
};

This works fine when I use a in a string context as it calls the toString method implicitly, but if I attempt to pass it to a function then it doesn't call toString and I am left with a sun.org.mozilla.javascript.internal.InterpretedFunction.

I have looked at the other Function.prototype methods (i.e. apply, bind, constructor, etc) to try and override the method which is called as the function is passed to another function but none of them fitted the bill. I am basically looking for a way of converting a Function to a string type object whenever it is used without the parenthesis - i.e a === a(). For people who might ask why don't I define a as a string to start with, my function returns a string constructed from other information the user has provided.

Maybe the solution is to make my users write syntactically correct JavaScript, but my users are far from programmers. I could also add some form of pre-parsing which checks for missing parenthesis and adds them in dynamically before I execute it using the ScriptEngine. However, although both of these options will work, I am looking for an easier way.

5
  • 3
    This is an XY problem. You're fixing a non-issue. In fact, higher-order functions are a feature, not a bug. Commented Nov 6, 2014 at 7:45
  • 2
    "Maybe the solution is to make my users write syntactically correct JavaScript". Yes, it is. "I could also add some form of pre-parsing which checks for missing parenthesis and adds them in dynamically before I execute it using the ScriptEngine." That would work too. Or even just thrown an error instead of fixing it. Commented Nov 6, 2014 at 7:46
  • 1
    Yep, I know I shouldn't be trying to hack JavaScript because my users can't use the correct syntax. Documentation is key to ensure the users know the correct syntax. Commented Nov 6, 2014 at 8:18
  • A clean solution to your problem(s) is to create your own language which would work exactly how you and your users want it to. Sounds like a lot of work at first, but given that most of the infrastructure (parsers, bytecode interpreters etc) is already there, it's actually much easier than trying to fix javascript and will end up far more robust and secure. Commented Nov 6, 2014 at 8:47
  • I agree and I have already done that for most of my application by creating a markup language for my users. However, I allow bits of native JavaScript to be included in my markup language. Commented Nov 6, 2014 at 9:23

1 Answer 1

1

Neither a.toString nor a.prototype.toString will allow you to forget the parenthesis. .toString allow you to do:

var a = function() {
  return "this is a";
};

a.prototype.toString = function () {
  return "something";
};

var A = new a;
alert(A + ''); // something

A.toString = function () {
  return "something else";
};

alert(A + ''); // something else

You shouldn't want in your code both a() and a return the same thing, this looks like a very bad idea.

An option to get myObject.myVar return a custom dynamic string is defineGetter https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/defineGetter

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.