1

Javascript:

var myfunc = function(foo, bar) {
  foo.thing();
  bar.stuff();
  };

if foo and bar will always be objects with functions thing and stuff, but foo and bar have not been declared as global variables because they could be any of a number of objects meeting this criteria, what is the proper way to declare myfunc?

And what if myfunc is a member of another object?

EDIT Less generic case (node.js/express):

var express = require("express");
app = express();
app.set("views", __dirname + "html");

var myfunc = function(req, res) {
  res.render("file.html");
  };

app.get("/", function(req, res) {
  myfunc(req, res);
  });
// ^ OR v    Tried both, but it doesn't get this far
app.get("/", myfunc(req, res));

app.listen(8080);

Errors state in var myfunc = function(req, res) { that res.render() is undefined.

6
  • Identifiers in the formal parameter list become local to the function as if they were declared, so there are no issues with undeclared variables. There will be issues if you don't pass callable objects as the first and second parameters though. Commented Aug 25, 2016 at 1:49
  • I don't understand the goal of this question. :D Do you need validation by the arguments or what? Commented Aug 25, 2016 at 1:51
  • are you asking about how to do actual function invocation?? Commented Aug 25, 2016 at 1:58
  • JavaScript is dynamically typed. You can't enforce the types of the variables just with the declaration. You will have to validate the parameters. Commented Aug 25, 2016 at 2:00
  • 1
    With your node.js code, you would use app.get("/", myfunc); and app.get will invoke your function with the 2 parameters. Commented Aug 25, 2016 at 2:04

4 Answers 4

1

EDIT: Specific Case

Change app.get("/", myfunc(req, res)); to app.get("/", myfunc);. This will run the function correctly.

Also, I believe app.set("views", __dirname + "html"); should be app.set("views", __dirname + "/html"); if the folder html exists inside the current directory.

Full Answer

JavaScript is Dynamically Typed

What you have there is perfectly fine. It is not necessary to have the foo and bar objects declared when you declare the myfunc() function.

However, you will have some issues if someone passes objects to myfunc that don't have the thing and stuff methods. So in order to avoid errors, there are a couple ways you can check.

Validate Methods

The first is to see if the objects have the proper methods:

var myfunc = function(foo, bar) {
    if (typeof foo.thing === 'function')
        foo.thing();
    if (typeof bar.stuff === 'function')
        bar.stuff();
};

Validate Object Instsance

You can also make sure that the objects are instances of the required class:

var Qux = function() {
    return {
        thing: function() {
            console.log('I am a thing!');
        },
        stuff: function() {
            console.log('Yikes! That\'s a bunch of stuff');
        }
    };
};

var foo = new Qux();
var bar = new Qux();

var myfunc = function(foo, bar) {
    if (foo instanceof Qux)
        foo.thing();
    if (bar instanceof Qux)
        bar.stuff();
};

myfunc(foo,bar);
Sign up to request clarification or add additional context in comments.

2 Comments

I made the initial example generic to be flexible, but removing the () in my specific instance fixed it. Also the /html was just a typo moving it into the question, my original code has the /. I will update the question to fix that.
Be careful with typeof tests. In less modern browsers, many of which are still in use, callable (host or exotic) objects may not return "function" and may return all sorts of values such as "unknown" or "object". There are also standard exotic and non–standard exotic objects.
0

What you have would be considered correct. You will just need to be careful to pass in objects that abide by the contract of myfunc. By that I mean you must be sure that the objects you pass in contain the functions thing() and stuff(), respectively.

Variables declared as parameters are local to that function. You don't need to worry about a global foo or bar interfering with myfunc. But, you must also realize if you do have those global variables defined they won't be used unless you explicitly pass them in.

Comments

0

The objects get redeclared as independent variables once inside, I would recommend reading you don't know JS here for a good primer on how the function gets declared and what happens implicitly to these objects:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch1.md

You still need to make some checks to make sure the objects you pass can be invoked, for that the top answer has a great method.

As far as it being part of another object there would be no problems outside of using this.

Comments

0

if you are asking about the actual function invocation you could simply do:

myfunc('obj1',obj2).

If myfunc is a property under another object, say obj3, then:

obj3.myfunc('obj1',obj2).

EDIT:

After the edit in OP.. the above ans is no longer relevant

You should be simply doing app.get("/", myfunc);

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.