我们说我有变量myvar
,而我不有变量myvar2
。我可以毫无问题地运行以下内容:
typeof myvar
// ⇒ 'string'
typeof myvar2
// ⇒ 'undefined'
typeof
和delete
是我所知道的唯一一个在给定未定义参数时不会抛出错误的函数。我看了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
答案 0 :(得分:6)
我想知道如何创建一个接受未解析引用的函数。
你不能。当您访问未声明的变量时,ReferenceError
会在函数被调用之前发生。在函数内部你无法从中恢复,因为它甚至没有被调用。
typeof和delete是我所知道的唯一一个在给定未定义参数时不会抛出错误的函数。
typeof
和delete
不是函数。这就是原因。
例如,检查传递给函数的可选变量是否已定义,并定义为字符串。
没有什么可以阻止你这样做。以下是有区别的:
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} );