最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typeof - Is it possible to pass undeclared variables as parameters in Javascript? - Stack Overflow

programmeradmin2浏览0评论

Let's say I have a variable myvar, and I don't have a variable myvar2. I can run the following without a problem:

typeof myvar
// ⇒ 'string'
typeof myvar2
// ⇒ 'undefined'

typeof and delete are the only functions I know of which don't throw errors when given an undefined parameter like this. I looked at the language spec for typeof and to my uninitiated eyes it seems to use internal functions like IsUnresolvableReference.

Edit: I'd been working in a language that checks type with a synonymous function, and hadn't noticed typeof is actually an operator in JavaScript. I've removed parentheses from the code here but left the above as written.

When I create a function:

function myFunc(input_variable) {
  return("hello");
}

... as expected this throws a ReferenceError when passed myvar2 as a parameter, unless I run var myvar2;.

If I wrap the return in a try/catch statement to handle the myvar2 not defined case, I still get the same error, as the variable seems to be checked for a resolvable reference upon entry into the function (upon runtime?) :

function myFunc(input_var) {
  try {
    return "hello";
  } catch(error) {
    if (error.name === 'ReferenceError'){
      return "world";
    }
  }
}

I was wondering how I can make a function that accepts unresolved references. My general guess is that, if it's a standard behaviour of functions, then perhaps I could modify some prototype for this construction specifically...? I'm aware prototypes are for objects, I'm wondering if this level of control over function is possible somehow?

By way of context, I always find myself writing function(input_var) :

if (typeof input_var == 'undefined' || my_settings.input_var_is_optional === true)
  var input_var = 'Sometimes variables are optional. This is my default value.';
  return dealWith(input_var);
} else if (typeof input_var == 'string') {
    return dealWith(input_var);
} else {
  // Already checked that input_var isn't optional, so we have a problem
  return false; // or throw a TypeError or something like that
}

but the verbosity of all that plain puts me off writing type checking into my code, making it less robust to use functions more freely, or to pass onto other developers.

I'd like to write a type handling function, e.g.

For a function myFunc(input_var), if the variable passed in as parameter input_var has been defined, check if it's a string, else set it as "default_value". If it wasn't defined, also set it as "default_value", else it's a valid string, so just use input_var as is.

...but it's sabotaged by the fact that I can't actually pass anything in that's undefined, effectively stopping me from isolating this plexity in a separate function to which I could just pass 2 parameters: input_var (the real deal, not just its name), and expected_type.

function typeTest(input_var, expected_type) {
  var is_optional_value = (typeof expected_type != 'undefined'
                                                 && expected_type === true);
  var optional_str = is_optional_value ? "|(undefined)" : ''
  var type_test_regex = RegExp('^(?!' + expected_type + optional_str + '$)');
  var is_expected_type = type_test_regex.test(typeof(input_var));
}

For example, to check that an optional variable passed into a function was both defined, and was defined as a string,

var myvar = 'abc'
//  myvar2 is never defined

// Mandatory type (expecting a string):
typeTest(myvar, 'string'); // true
// if (/^(?!string)$)/.test(typeof(myvar))
typeTest(myvar2, 'string'); // throws error

// Mandatory type (expecting a number):
typeTest(myvar, 'number'); // false
typeTest(myvar2, 'number'); // throws error

// Optional type ("expected is true"):
typeTest(myvar, true); // true
// if (/^(?!string|(undefined)$)/.test(typeof(myvar))
typeTest(myvar2, true); // throws error

Let's say I have a variable myvar, and I don't have a variable myvar2. I can run the following without a problem:

typeof myvar
// ⇒ 'string'
typeof myvar2
// ⇒ 'undefined'

typeof and delete are the only functions I know of which don't throw errors when given an undefined parameter like this. I looked at the language spec for typeof and to my uninitiated eyes it seems to use internal functions like IsUnresolvableReference.

Edit: I'd been working in a language that checks type with a synonymous function, and hadn't noticed typeof is actually an operator in JavaScript. I've removed parentheses from the code here but left the above as written.

When I create a function:

function myFunc(input_variable) {
  return("hello");
}

... as expected this throws a ReferenceError when passed myvar2 as a parameter, unless I run var myvar2;.

If I wrap the return in a try/catch statement to handle the myvar2 not defined case, I still get the same error, as the variable seems to be checked for a resolvable reference upon entry into the function (upon runtime?) :

function myFunc(input_var) {
  try {
    return "hello";
  } catch(error) {
    if (error.name === 'ReferenceError'){
      return "world";
    }
  }
}

I was wondering how I can make a function that accepts unresolved references. My general guess is that, if it's a standard behaviour of functions, then perhaps I could modify some prototype for this construction specifically...? I'm aware prototypes are for objects, I'm wondering if this level of control over function is possible somehow?

By way of context, I always find myself writing function(input_var) :

if (typeof input_var == 'undefined' || my_settings.input_var_is_optional === true)
  var input_var = 'Sometimes variables are optional. This is my default value.';
  return dealWith(input_var);
} else if (typeof input_var == 'string') {
    return dealWith(input_var);
} else {
  // Already checked that input_var isn't optional, so we have a problem
  return false; // or throw a TypeError or something like that
}

but the verbosity of all that plain puts me off writing type checking into my code, making it less robust to use functions more freely, or to pass onto other developers.

I'd like to write a type handling function, e.g.

For a function myFunc(input_var), if the variable passed in as parameter input_var has been defined, check if it's a string, else set it as "default_value". If it wasn't defined, also set it as "default_value", else it's a valid string, so just use input_var as is.

...but it's sabotaged by the fact that I can't actually pass anything in that's undefined, effectively stopping me from isolating this plexity in a separate function to which I could just pass 2 parameters: input_var (the real deal, not just its name), and expected_type.

function typeTest(input_var, expected_type) {
  var is_optional_value = (typeof expected_type != 'undefined'
                                                 && expected_type === true);
  var optional_str = is_optional_value ? "|(undefined)" : ''
  var type_test_regex = RegExp('^(?!' + expected_type + optional_str + '$)');
  var is_expected_type = type_test_regex.test(typeof(input_var));
}

For example, to check that an optional variable passed into a function was both defined, and was defined as a string,

var myvar = 'abc'
//  myvar2 is never defined

// Mandatory type (expecting a string):
typeTest(myvar, 'string'); // true
// if (/^(?!string)$)/.test(typeof(myvar))
typeTest(myvar2, 'string'); // throws error

// Mandatory type (expecting a number):
typeTest(myvar, 'number'); // false
typeTest(myvar2, 'number'); // throws error

// Optional type ("expected is true"):
typeTest(myvar, true); // true
// if (/^(?!string|(undefined)$)/.test(typeof(myvar))
typeTest(myvar2, true); // throws error
Share Improve this question edited Mar 17, 2015 at 19:34 Louis Maddox asked Mar 17, 2015 at 16:49 Louis MaddoxLouis Maddox 5,5766 gold badges42 silver badges69 bronze badges 10
  • 3 Let me ask you this: why would you ever want that? The fact that typeof(myvar2) works even when myvar2 is not defined seems like an epic JavaScript fail to me. BTW: neither typeof nor delete are functions. These are keywords and that's why this works. – freakish Commented Mar 17, 2015 at 16:53
  • 5 +1 You should never need to check whether a variable has been declared at runtime. What problem are you trying to solve? – SLaks Commented Mar 17, 2015 at 16:54
  • 1 Optional parameters are useful in functions with default settings. I want to write functions that have default values, like I said above. The thing that wouldn't be declared is the optional parameter - I'd use a default value in its place. Thanks @MichaelP. I'll edit the title. – Louis Maddox Commented Mar 17, 2015 at 16:56
  • 2 @Louis Optional parameters are declared. They just don't have a value. So the premise of your question is flawed. – JLRishe Commented Mar 17, 2015 at 17:02
  • 3 @freakish its not an epic fail of js.You can check whether a variable is defined or not ,without any exceptions – balajisoundar Commented Mar 17, 2015 at 17:07
 |  Show 5 more ments

3 Answers 3

Reset to default 6

I was wondering how I can make a function that accepts unresolved references.

You can't. When you access an undeclared variable, the ReferenceError occurs before the function even gets called. There's nothing you can do inside the function to recover from this, because it hasn't even been called.

typeof and delete are the only functions I know of which don't throw errors when given an undefined parameter like this.

typeof and delete are not functions. That's why.

For example, to check that an optional variable passed into a function was both defined, and was defined as a string.

There's nothing stopping you from doing this. There is a difference between:

  • variables with the value undefined
  • parameters that have not been passed a value
  • undeclared variables.

There is no problem in dealing with the first two:

function hasType(val, type) {
  return typeof val === type;
}

function myFunc(param1, param2) {
  console.log('param1: ', hasType(param1, 'string'));
  console.log('param2: ', hasType(param2, 'string'));
}

myFunc('hello');

There is no need to check whether someone is trying to call your functions with undeclared variables. If they are, then the problem is with their code and they need to fix it. If they are taking advantage of optional parameters, that is a different matter, and you can handle for that scenario just fine.

as the variable seems to be checked for a resolvable reference upon entry into the function

It is checked before entry.

Given foo(bar), the logic for resolution is "Get foo, then get bar, then call foo with the value of bar as an argument.

If bar isn't declared then you'll get a ReferenceError before the function is called in the first place.

typeof and delete are the only functions I know of which don't throw errors when given an undefined parameter like this.

From the documentation you link to:

The typeof Operator
The delete Operator

They aren't functions.


I was wondering how I can make a function that accepts unresolved references.

You can't.

For example, to check that an optional variable

If you want an argument to be optional then either:

Explicitly pass undefined:

typeTest(undefined, 'string');

Put the optional argument last in the arguments list:

typeTest('string');

Pass an object:

typeTest({ argument_name: 'string' });

You can using a function slide.

function attempt(f){
    console.log(f());
}
attempt( function (){ return  nomansland} );
//later an ajax call declares it:
var nomansland = "ok";
attempt( function (){ return  nomansland} );
发布评论

评论列表(0)

  1. 暂无评论