这更像是一般性实践问题。
我正在使用的语言是Javascript。我有一个函数正在获取一个包含许多变量的对象(好吧,只有10个变量)。确保此函数获取所有必需变量并且它们都已设置的最佳方法是什么?
我知道,我知道,为什么不使用if
声明。这是if语句中的一小部分!随着我成长为程序员,我知道这可能不是最好的方法。我正在寻找一条捷径。如何你检查存在的大量变量和非空值?
答案 0 :(得分:1)
这是处理验证的一种非常巧妙的方法,我通常在检查表单输入中的必填字段时使用它。
var theObj = { /* object loaded from server */ }
function checkTheObj(testObj)
{
var requiredKeys = ['key1', 'key2', 'key3'];
for(var keyPos = 0; keyPos < requiredKeys.length; keyPos++)
{
if(typeof(testObj[requiredKeys[keyPos]]) == 'undefined')
{
return false;
}
}
return true;
}
if(checkTheObj(theObj))
{
//do stuff
}
你当然可以调整它来返回或抛出一个异常,告诉第一个丢失的字段(或使用内部数组返回所有缺失字段的列表)。
答案 1 :(得分:1)
function objectHas(obj, properties) {
var len = properties.length
for (var i=0; i<len; i++) {
if (i in properties) {
if((!obj.hasOwnProperty(properties[i])) || (!obj.propertyIsEnumerable(properties[i]))) {
return false;
}
}
}
return true;
}
用法:
if(objectHas(user, ["email", "password", "phone"])) {
console.log("awesome");
}
这很简单,但是做到了。
编辑:在一个理想的世界中,您可以扩展Object原型以获得更简洁的语法,例如 if(object.has([“a”,“b”,“c”])) ,但显然扩展了Object原型是incarnation of evil,所以函数必须这样做:)
答案 2 :(得分:1)
首先,您需要提高对这些语言的理解并学习正确的术语。
eval
代码可以包含变量;这是不同(但相似)的概念。作为程序员,您应该已经知道可以循环执行重复性任务; ECMAScript实现中的关联语句是Netscape/Mozilla JavaScript (in Mozilla-based software like Firefox)。所以你不必须写几个if
语句。
您可以通过两种方式访问for
, for
-in
, while
and do
,其中property
是属性名称:
obj.property
obj["property"]
如果属性名称是标识符,则第二个等同于第一个,即它是否遵循某些命名规则。如果属性名称不是标识符,或者它是可变的,则必须使用第二个。这也表明所有属性名称是字符串值。因此,您可以将属性的名称存储为变量或其他属性的值,然后访问属性访问器中的变量或属性。在下文中,属性名称(property
)存储在变量中并使用:
var propertyName = "property";
obj[propertyName]
将它与循环结合使用可以迭代对象的某些属性。遗憾的是,到目前为止提供的解决方案在两个方面存在缺陷:for
- in
语句仅针对对象的可枚举属性进行迭代,并且在任意订单。此外,它还会迭代可枚举的继承的属性(这就是为什么一个解决方案需要hasOwnProperty()
调用)。
一种简单,可靠且有效的方法,只按定义的顺序迭代对象的某些属性,如下所示:
var propertyNames = ['name1', 'name2', 'name3'];
for (var i = 0, len = propertyNames.length; i < len; ++i)
{
/* … */ myObject[propertyNames[i]] /* … */
}
这是有效的,因为propertyNames
引用了一个Array
实例,它封装了一个数组数据结构。数组的元素是Array
实例的属性,其整数索引从0到65535(2 32 -1)。因为索引不是标识符(它们以十进制数字开头),所以你必须使用括号属性访问器语法(有些人误解了这一点,并将所有ECMAScript对象称为“数组”,甚至将它们称为“关联数组”和{{1 “数组运算符”)。因此,[…]
计算每次迭代中数组元素的值,因为propertyNames[i]
每次增加1。因此,i
在每个循环中访问具有该名称的属性。
现在,要确定属性是否已设置,您需要定义这意味着什么。访问不存在的属性会导致myObject[propertyNames[i]]
值(不是错误)。但是,现有属性也可能具有undefined
值作为其值。
如果“未设置”表示该对象没有该属性(但可以继承它),那么您应该使用Mahn解决方案中使用的undefined
。
如果“未设置”表示该对象没有该属性且未继承该属性,则应使用hasOwnProperty()
运算符,前提是该对象不 a { {3}}(因为properties of an object host object):
in
如果“未设置”表示对象具有或继承该属性,但该属性具有if (propertyNames[i] in obj)
值,或者该对象既没有也没有继承该属性,那么您应该使用{{1}在Bob Davies和aetaur的解决方案中使用的运算符(但后者使用the in
operator的方法原样不太兼容;该方法在ECMAScript Edition 5之前未指定,并且在IE / JScript中不可用&lt; 9 )。
ECMAScript Edition 5.x有第三个选项,is not specified for them(尽管名称)返回对undefined
实例的引用,该实例包含所有未继承属性的名称。参数:
typeof
如果它不是内置的,那么模仿Array
是个好主意,因为这种算法经常有用。
答案 3 :(得分:0)
如果variableNameList
中所有变量(所需变量名称列表)在对象o
中设置,则此表达式返回true:
variableNameList.every(function(varName){ return typeof o[varName] !== 'undefined'; });
您可以使用下划线_.all
功能代替原生every
,并使用下划线_.isUndefined
代替typeof ...
。