是否可以在Javascript中将未声明的变量作为参数传递?

时间:2015-03-17 16:49:44

标签: javascript typeof

我们说我有变量myvar,而我有变量myvar2。我可以毫无问题地运行以下内容:

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

typeofdelete是我所知道的唯一一个在给定未定义参数时不会抛出错误的函数。我看了the language spec for typeof并且对我不熟悉的眼睛似乎使用了像IsUnresolvableReference这样的内部函数。

  

修改:我一直在使用a synonymous function检查类型的语言,并且没有注意到typeof实际上是JavaScript中的运算符。我从这里的代码中删除了括号,但是上面写着。

当我创建一个函数时:

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

...正如预期的那样,当ReferenceError作为参数传递时会抛出myvar2,除非我运行var myvar2;

如果我在try / catch语句中包装返回以处理 myvar2未定义的情况,我仍然会得到相同的错误,因为变量似乎是在进入函数时检查可解析的引用(在运行时?):

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

我想知道如何创建一个接受未解析引用的函数。我的一般猜测是,如果它是一个标准的函数行为,那么也许我可以修改这个结构的一些原型......我知道原型是用于对象的,我想知道对function的这种控制级别是否可能以某种方式进行?

通过上下文,我总是发现自己写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
}

但是所有那些简单的冗长使我无法将类型检查写入我的代码中,使得使用函数的可靠性降低,或者传递给其他开发人员。

我想写一个类型处理函数,例如

  

对于函数myFunc(input_var),如果已定义作为参数input_var传入的变量,请检查它是否为字符串,否则将其设置为"default_value"。如果没有定义,也可以将其设置为"default_value",否则它是有效字符串,因此请按原样使用input_var

......但是它被我无法通过任何未定义的事实所破坏,实际上阻止我在一个单独的函数中将这种复杂性隔离开来传递2个参数:input_var(真实交易,而不仅仅是其名称)和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));
}

例如,要检查传递给函数的可选变量是否已定义,并且被定义为字符串,

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

3 个答案:

答案 0 :(得分:6)

  

我想知道如何创建一个接受未解析引用的函数。

你不能。当您访问未声明的变量时,ReferenceError会在函数被调用之前发生。在函数内部你无法从中恢复,因为它甚至没有被调用。

  

typeof和delete是我所知道的唯一一个在给定未定义参数时不会抛出错误的函数。

typeofdelete不是函数。这就是原因。

  

例如,检查传递给函数的可选变量是否已定义,并定义为字符串。

没有什么可以阻止你这样做。以下是有区别的:

  • 值为undefined
  • 的变量
  • 尚未传递值的参数
  • 未声明的变量。

处理前两个问题没有问题:



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');




无需检查是否有人试图使用未声明的变量调用您的函数。如果是,那么问题在于他们的代码,他们需要修复它。如果他们正在利用可选参数,这是另一回事,您可以正好处理该场景。

答案 1 :(得分:3)

  

因为变量似乎在进入函数

时检查了可解析的引用

在条目之前检查

鉴于foo(bar),解析的逻辑是“获取foo,然后获取bar,然后使用值foo作为参数调用bar

如果未声明bar,那么在首先调用函数之前,您将获得ReferenceError。

  

typeof和delete是我所知道的唯一一个在给定未定义参数时不会抛出错误的函数。

从您链接的文档:

  

运算符的类型   删除运算符

它们不是功能。


  

我想知道如何创建一个接受未解析引用的函数。

你做不到。

  

例如,要检查可选变量

如果你想让一个参数是可选的,那么:

明确传递undefined

typeTest(undefined, 'string');

将可选参数放在参数列表的最后:

typeTest('string');

传递一个对象:

typeTest({ argument_name: 'string' });

答案 2 :(得分:1)

您可以使用功能幻灯片。

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