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

What is the most efficient way for checking if an object parameter has all require properties?

本文关键字:属性 有效 是什么 方法 参数 对象 是否 检查      更新时间:2023-09-26

在javascript中,使用对象参数是我处理函数的首选方式。为了检查函数是否具有所需的参数,我要么(Solution 1)遍历所有对象参数属性并抛出错误,要么(Solution 2)等待,直到需要一个所需的属性并抛出一个错误。解决方案二看起来很有效,但我必须在函数中的多个位置进行抛出。Solution 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本身添加一个方法:

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

它读起来几乎像自然语言。"取所需的参数,它们中的每一个都在参数对象中吗?"。

只需将其包装在function checkParams(paramObj, requiredParams)中即可轻松重复使用。

更普遍地说,这是询问一个列表(在这种情况下是所需参数的列表)是否包含在另一个列表中(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