2

Is there a way in JavaScript to call a function without parentheses?

For example in jQuery:

$('#wrap').text("asdf"); will work and so will $.ajax(ajaxOptions);

I'm mapping a function (class) to window.$ that has a set of functions I want to be able to call with or without parentheses. Like jQuery.

Here's a code example:

function Test(asdf) {
  this.test = function(testVar) { return testVar + ' asdf'; }
}

And I map Test() to $:

window.$ = new Test();

I have to call the function (class) like this:

$('asfd').test('ASDF');

But I want to be able to call it like this:

$.test('asdf');
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
errorhandler
  • 147
  • 2
  • 2
  • 7
  • 3
    Could you please give an example of how these would look "without parentheses", or how you would like to be calling them? – Shane Reustle Oct 14 '10 at 03:07
  • Your example, for lack of a better word: "sucks". In both cases you're calling a function w/ parentheses – vol7ron Oct 14 '10 at 03:53
  • You know what, I didn't want to do this b/c ur new, but -1. This is a poorly asked and demonstrated question. – vol7ron Oct 14 '10 at 03:56
  • This question is still so poorly specified as to be unintelligible. `Test` is a constructor, so `new Test()` creates an object. In the sample, the new object isn't a function, so `$` isn't a function. `$.test('asdf')` works fine; what will fail is `$('asfd').test('ASDF')`. Also, JS doesn't natively have classes, so "classes" only makes sense if you've created your own inheritance scheme that uses classes. – outis Nov 29 '11 at 05:02

7 Answers7

38

JavaScript is extremely flexible since objects are basically a map and can contain any number of key value pairs, where the value itself can be an object and thus you get nesting. Another interesting aspect of JavaScript is that functions are themselves first class objects, so in a key value pair, you can have a function as a value.

To get something like jQuery then becomes very simple. You start off with a function (constructor function, or class if you will),

function myFunction() {
    // do some awesome web 2.0 stuff
}

Since myfunction is a function and also an object, so you attach key value pairs to it as well which is what jQuery does. To verify that myFunction is also an object, do an instanceof check:

myFunction instanceof Function; // true
myFunction instanceof Object; // true

So we can add properties to a function which could be simple values, or functions themselves.

// adding a simple property that holds a number
myFunction.firstPrime = 2;

// adding a function itself as a property to myFunction
myFunction.isPrime = function(number) {
    // do some magic to determine if number is prime
};

But if that is not your question, and you really want to know if you can literally call a function without using parentheses, then the answer is yes, you can, using the additions in ECMAScript 5th ed.

Here's an example of calling a function without using parentheses using Object.defineProperty and defining it as a getter:

var o = {};

Object.defineProperty(o, "helloWorld", {
    get: function() {
        alert("hello world");
    },
    set: undefined
});

o.helloWorld; // will alert "hello world"

Try this example in Chrome or Safari, or Firefox nightly.

Anurag
  • 140,337
  • 36
  • 221
  • 257
5

new


You can call a function using new. The twist is, within the function this becomes an object being constructed by the function instead of whatever it would normally be.

function test () { alert('it worked'); }
...
new test; // alerts "it worked"

call and apply


You can use call or apply to call a function indirectly. You'll still need parentheses (unless you use new), but you won't be directly invoking the function with parentheses.

Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
5
function message() {return "Hello crazy world!"; }
Function.prototype.toString = function() { return this.call(this); };
alert(message);
Mikhail Nasyrov
  • 900
  • 1
  • 8
  • 14
  • 9
    I'm counting 8 parentheses in this answer. – phihag Feb 04 '13 at 14:03
  • While this may not address the question as it is described in detail, it does answer the *question itself* of "how to call a function without parenthesis". – Synexis Apr 10 '16 at 03:42
1

The difference in those examples is that .text() is a function on jQuery objects (instances of them, wrappers of elements), it's on $.fn (jQuery's prototype shortcut) so it's specifically for jQuery objects.

$.ajaxSetup() is a method on the jQuery object/variable itself.

If you look at the API it's easy to tell which methods are where, the jQuery.something() methods are methods on the jQuery variable/object, not related to an element set, everything else that's just .something() are the methods to run against element sets (on jQuery object instances).

For what you want to do, yes it is possible, but it doesn't make much sense, for example:

$.myFuntion = $.fn.myFunction = function() { alert('hi'); };

You should place your methods where it makes sense, if it's for a set of elements, use $.fn.myFunction and this refers to the set of elements inside. If it's a static method unrelated to an element set place it outside separately or possibly at $.myFunction.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • @errorhandler - It really doesn't make any sense without jQuery as an example...since that's the only example you provided I have no idea what you mean by "without" parenthesis if you're not referring to what I am in the answer. – Nick Craver Oct 14 '10 at 03:14
  • 2
    @errorhandler - It still doesn't make any sense, you should give an example of calling "without parenthesis", even jQuery doesn't do this really. `$` is a function `$("#wrap")` is a function call that returns a jQuery object, you're calling `.text()` on *that* object. In the `$.ajax()` case you're calling the `ajax` method on `$`, but you're using parenthesis in both cases. – Nick Craver Oct 14 '10 at 03:17
  • @errorhandler - Now I'm more confused, since your example *does* work with `$.test()`, you can try it here: http://jsbin.com/arolu3 – Nick Craver Oct 14 '10 at 03:29
  • its not working on my larger project..... also I just realized that my function also accepts one variable eg `function Test(asdf) { ...` – errorhandler Oct 14 '10 at 03:32
0

You can make a function reference, but you won't be able to pass arguments:

function funky() { alert("Get down with it"); }

obj.onclick = funky;
Ben
  • 54,723
  • 49
  • 178
  • 224
  • 6
    More importantly, that doesn't ***call*** the function. That's simply assigning another name (`obj.onclick`) by which you can refer to the function if you call it later. – VoteyDisciple Oct 14 '10 at 03:19
0

You can try something like this

var test = {
    method1 : function(bar) {
        // do stuff here
        alert(bar);
    },
    method2 : function(bar) {
        // do stuff here
        alert(bar);
    }
};

test.method1("foo");
test.method2("fooo");
mikefrey
  • 4,653
  • 3
  • 29
  • 40
  • 41
    How the heck is this not using parentheses? – Dagg Nabbit Oct 14 '10 at 03:45
  • 2
    This answer makes no sense in regards to the question. `test` isn't even a function, it's a pure object. In both cases my eyes are seeing parentheses. – vol7ron Oct 14 '10 at 03:55
  • 7
    Actually, this makes perfect sense. errorhandler was asking how to mimic the jQuery $ object. The title of the question was not necessarily posed correctly, but I felt I understood what they were looking for after reading the entire question and looking at the examples they provided. Also, my answer was accepted, so I shouldn't have to defend it. – mikefrey Oct 14 '10 at 13:26
0

Use template literals:

alert`WOW`

It is cleaner and shorter, without having to rely on jQuery, call, etc.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131