0

I've looked a fair bit, so pardon me if this has already been answered.

I'm also curious as to what the actual term is called; Is it "Ambiguous" for the type of arguments I am handling?

Anyways, the problem is that I want to be able to call a function like this:

prompt(_.define(variable, "DEFAULT VALUE")); 

Basically, so that variables can have default values.

However, every time I try to do this, I get this error:

Timestamp: 6/11/2012 1:27:38 PM
Error: ReferenceError: thisvarisnotset is not defined
Source File: http://localhost/js/framework.js?theme=login
Line: 12

Here is the source code:

function _() {
return this;
};

(function(__) {
__.defined = function(vrb, def) {
    return typeof vrb === "undefined" ? ((typeof def === "undefined") ? null : def) : vrb;
    };
})(_());


prompt(_.defined(thisvarisnotset, "This should work?"), "Can you see this input?");

Not sure why it's doing this? I've called undefined variables as arguments in functions before and it worked just fine.

John Som
  • 11
  • 1
  • 2
  • Yeah, you can't do this in javascript. – Esailija Jun 11 '12 at 17:44
  • `variable = variable || 'default';` – jbabey Jun 11 '12 at 17:50
  • `var variable = variable || 'default';` would be better, since you don't know if variable is initialised yet. Otherwise, you will be initialising `variable` in the global scope. – Cameron Martin Jun 11 '12 at 17:56
  • Thanks, that makes things a little bit more simple than what I was previously doing, the (var || 'default'). I didn't know that you can not pass undefined variables that way, I figured that the function would automatically assign it as undefined if it was. Thank you! – John Som Jun 11 '12 at 18:08

2 Answers2

1

A completely undeclared variable can't be passed in JS; you can only pass declared variables or undeclared properties of other variables.

In other words:

var a; // you can do _.defined(a)
var a = undefined; // you can do _.defined(a)
a.b; // you can do _.defined(a.b), even though we never defined b
machineghost
  • 33,529
  • 30
  • 159
  • 234
  • To fix your code, one option is to do this all the time "window.thisvarisnotset"; since window is the global scope, this should work. Of course, it bears mentioning that you're almost trying to create a new variant of JS here; good luck to anyone else who has to work with your code. – machineghost Jun 11 '12 at 17:46
  • If `thisvarisnotset` if not declared elsewhere, it will refer to `window.thisvarisnotset`. This doesn't solve the problem though. – Cameron Martin Jun 11 '12 at 17:53
  • Oh, good point. Yeah, really you're trying to change JS, and that can't be done. The much more JS-ish solution to this, as ddlshack mentioned, is to just do "thisvarisnotset || defaultValue" everywhere, instead of even trying to define a function like the one you're trying to make. – machineghost Jun 11 '12 at 17:58
  • (Well, and even MORE JS-ish solution would be to restructure your code so that it doesn't rely on ambiguously declared variables in the first place ...) – machineghost Jun 11 '12 at 18:01
  • (... the foo || default pattern is useful, and you'll find it used in major libraries like jQuery, but you should only need it in a few specific situations; not so much that you feel like you need to make a function. If you do feel like you need it a lot, there's probably a better way to do what you're trying to accomplish.) – machineghost Jun 11 '12 at 18:08
  • There's nothing wrong with doing `foo = foo || bar`. It equivalent to `if(!foo) { foo = bar; }`. – Cameron Martin Jun 11 '12 at 19:10
  • Agreed; I never said there was anything wrong with it :-) However, if you're constantly checking (whether with ||, or typeof != 'undefined', or whatever) for whether a variable exists or not all over your code, to the point where you start trying to write a function to do it for you, then something is very likely wrong. If one is writing normal, well-written Javascript, there should not be *that* many cases where one doesn't know whether a variable exists or not. – machineghost Jun 11 '12 at 20:08
  • The main reason I can think is to detect whether native functions are available, and if not, provide a javascript one. Also, its useful to give default values to function arguments. – Cameron Martin Jun 11 '12 at 20:15
  • Exactly; there's probably a couple more cases we're both forgetting, and aside from that one really should know what one's variables are ... – machineghost Jun 11 '12 at 20:41
1

Basically, so that variables can have default values.

Why don't you just initialize the variable with a default value?

Or, just initialise the variable before calling defined.

var variable; // Note that this will not overwrite the variable if it is already set.

Or, even better.

var variable = variable || 'default';
Cameron Martin
  • 5,952
  • 2
  • 40
  • 53