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

Lou*_*dox 5 javascript typeof

假设我有一个变量myvar,而且我没有变量myvar2.我可以运行以下没有问题:

typeof myvar
// ? 'string'
typeof myvar2
// ? 'undefined'
Run Code Online (Sandbox Code Playgroud)

typeof并且delete是唯一的功能,我知道其中给出这样一个未定义的参数时不抛出错误.我查看了语言规范typeof以及我不熟悉的眼睛,它似乎使用了内部函数IsUnresolvableReference.

编辑:我一直在使用一种用同义函数检查类型的语言,并且没有注意到typeof它实际上是JavaScript中的运算符.我从这里的代码中删除了括号,但是上面写了.

当我创建一个函数时:

function myFunc(input_variable) {
  return("hello");
}
Run Code Online (Sandbox Code Playgroud)

...正如预期的那样,除非我跑,否则抛出一个作为参数ReferenceError传递的myvar2时间var myvar2;.

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

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

我想知道如何创建一个接受未解析引用的函数.我的一般猜测是,如果它是函数的标准行为,那么也许我可以专门修改这个结构的一些原型......?我知道原型是针对物体的,我想知道这种控制水平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
}
Run Code Online (Sandbox Code Playgroud)

但是所有那些简单的冗长使我无法将类型检查写入我的代码中,使得使用函数更加自由,或者传递给其他开发人员.

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

对于函数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));
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

JLR*_*she 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');
Run Code Online (Sandbox Code Playgroud)

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