Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 检查对象参数是否具有所有必需属性的最有效方法是什么?_Javascript - Fatal编程技术网

Javascript 检查对象参数是否具有所有必需属性的最有效方法是什么?

Javascript 检查对象参数是否具有所有必需属性的最有效方法是什么?,javascript,Javascript,在javascript中,使用对象参数是我处理函数的首选方式。要检查函数是否具有必需的参数,我可以(解决方案1)循环所有对象参数属性并抛出错误,或者(解决方案2)等待直到需要必需的属性并抛出错误。解决方案2似乎很有效,但我必须在函数中的多个位置抛出解决方案1看起来很实用,但可能是一段可重用的代码。还有其他解决方案吗?您确实可以这样做 var propsNeeded = ["prop1", "prop2", "blah", "blah", "blah"], obj = { prop1: "H

在javascript中,使用对象参数是我处理函数的首选方式。要检查函数是否具有必需的参数,我可以(
解决方案1
)循环所有对象参数属性并抛出错误,或者(
解决方案2
)等待直到需要必需的属性并抛出错误。解决方案2似乎很有效,但我必须在函数中的多个位置抛出<代码>解决方案1看起来很实用,但可能是一段可重用的代码。还有其他解决方案吗?

您确实可以这样做

var propsNeeded = ["prop1", "prop2", "blah", "blah", "blah"], 
obj = {
  prop1: "Hi"
}
function hasRequiredProperties(props, obj){
   return Object.keys(obj).sort().join() == propsNeeded.sort().join();
}
console.log(hasRequiredProperties(propsNeeded, obj)); // false
您可以检查单个属性,如

function hasProperty(propName, obj){
  return obj.hasOwnProperty(propName);
}

为了保持一致性,我将创建
require
方法,并在需要某些属性时始终使用它

var require = function (key, object) {

    if (typeof object[key] === 'undefined') {
        throw new Error('Required property ' + key + ' is undefined');
    }
};
只要我确定该属性是必需的,我就会测试该属性是否存在。像这样:

var example = function (args) {

    require('alwaysRequired', args);

    // some code here which uses property alwaysRequired

    if (args.something) {
        require('sometimesRequired', args);

        // some code here which uses property sometimesRequired
    }
};

使用@Amit的答案,我可能会向
对象本身添加一个方法:

Object.prototype.hasAllProperties = function(props, fire){
    var result = Object.keys(this).sort().join() == propsNeeded.sort().join();

    if (fire && !result){
        throw new Error('Object does not define all properties');
    }

    return result;
}
在你的职能中:

function someFunction(myObject){
    var objComplete = myObject.hasAllProperties(["prop1", "prop2", "prop3"], false);
}
更新:

注意到@Amit原始答案的问题后,我建议如下:

Object.prototype.hasAllProperties = function(props, fire){
    var result = true;

    $(props).each(function(i, e){
        if (!this.hasOwnProperty(e) ) {
             result = false;
             return false;
        }
    });

    if (fire && !result){
        throw new Error('Object does not define all properties');
    }

    return result;
}

这只是检查对象上是否存在键的一般情况,使用

requiredParams.every(function(prop) { return prop in paramObj; })
它读起来几乎像自然语言。“获取所需参数时,参数对象中是否包含所有参数?”

只需将其包装在
函数checkParams(paramObj,requiredparms)
中,以便于重用

更一般地说,这是询问一个列表(在本例中是所需参数的列表)是否包含在另一个列表(params对象上的键)中的问题。因此,我们可以编写一个列表包含的常规例程:

function listIncluded(list1, list2) {
    return list1.every(function(e) { return list2.indexOf(e) !== -1; });
}
然后我们的参数检查就变成了

function checkParams(paramObj, requiredParams) {
    return listIncluded(requiredParams, Object.keys(paramObj));
}

如果您想知道对象是否至少具有某些属性,则可以在不使用第三个参数的情况下使用此函数:

function hasRequiredProperties(propsNeeded, obj, strict) {

  if (strict) return Object.keys(obj).sort().join() == propsNeeded.sort().join();

  for (var i in propsNeeded ) {
    if (!obj.hasOwnProperty(propsNeeded[i])) return false;
  }
  return true;
};
例如:

 options = {url: {
        protocol: 'https:',
        hostname: 'encrypted.google.com',
        port: '80'
      }
    };

    propsNeeded = ['protocol', 'hostname'];

    hasRequiredProperties(propsNeeded, options.url); // true

    hasRequiredProperties(propsNeeded, options.url, true); // false

此解决方案解决了同时检查多个属性的问题,@Matti solutions将调用多个调用OP使用术语“必需参数”,这表明可能还存在“非必需(可选)”参数。该程序消除了可选参数的可能性;它检查传入的参数是否与所需参数完全相同。除此之外,通过比较两个数组的字符串表示形式来比较两个数组的方法似乎有点奇怪,不是吗?虽然这个bug在现实生活中几乎不会出现,但是如果“a”和“b”是必需的参数,那么如果传入的对象是
{“a,b”:true}
@torazaburo,那么这个例程将报告成功。好吧,我已经包括了单次使用版本:)谢谢btww您为什么要这样做,特别是作为原型上的枚举属性,而且当“算法”出现错误时(参见@AmitJoki的答案的评论)?@torazaburo是的,你是对的。乍一看@AmitJoki的回答似乎是可行的。我已经更新了答案,谢谢。