如何在JavaScript中描述函数的参数位置

How to describe the location of a parameter to a function in JavaScript

本文关键字:函数 参数 位置 描述 JavaScript      更新时间:2023-09-26

我不确定我在主题中是否很好地描述了这个问题。我不确定"location"是否是描述嵌套在对象中的参数位置的正确方式。

下面是我创建的一个函数,它搜索一个对象数组,并返回具有特定值属性的第一个对象的索引。

function indexOfItemWithParam( items, location, value ) {
    var itemsIndex,
        directions = location.split( '.' ),
        directionsIndex,
        property;
    for( itemsIndex = 0; itemsIndex < items.length; itemsIndex++ ) {
        property = items[ itemsIndex ];
        for( directionsIndex = 0; directionsIndex < directions.length; directionsIndex++ ) {
            property = property[ directions[ directionsIndex ] ];
        }
        if( property == value ) {
            return itemsIndex;
        }
    }
    return false;
}

此函数的特殊之处在于,如果您有包含对象的对象,则可以描述对象层次结构中某个属性的位置。

var people = [
    {
        id: 1,
        names: {
            first: 'John',
            last: 'Smith'
        },
        age: 45
    },
    {
        id: 2,
        names: {
            first: 'Jane',
            last: 'Jones'
        },
        age: 30
    },
];
console.log( indexOfItemWithParam( people, 'names.first', 'Jane' ) );

控制台将返回索引位置1。具有属性names且属性first值为Jane的第一个对象的位置。正如您所看到的,我正在传递一个字符串,该字符串模仿在JavaScript中导航对象的方式,使用句号作为分隔符将其拆分为一个数组,然后循环浏览每个项目以浏览对象。

这感觉很奇怪,好像应该有更好的方法来做这件事。我找不到任何其他函数试图做类似事情的例子。这种方法,即传递字符串、分解和循环,是导航嵌套对象的最佳方式吗?

我找不到任何其他函数试图做类似事情的例子。

事实上,有很多这样的例子,看看用字符串键访问嵌套的JavaScript对象,或者将点符号中的JavaScript字符串转换为对象引用。

这种方法,即传递字符串、分解和循环,是导航嵌套对象的最佳方式吗?

没有。循环对于访问嵌套属性是非常必要的,但不应将路径作为字符串传递。让您的函数立即获取数组。这更加方便和通用:

  • 您没有责任(正确)解析/分解字符串
  • 通常情况下,调用者也是泛型的,并且已经使用了数组
  • 无需担心边缘情况(如数组索引、符号键或包含点的属性名)

function indexOfItemWithParam(items, path, value) {    
    for (var itemsIndex = 0; itemsIndex < items.length; itemsIndex++ ) {
        var property = path.reduce(function(property, direction) {
            return property[direction];
        }, items[itemsIndex]);
        if (property === value)
            return itemsIndex;
    }
    return -1;
}
// call as
indexOfItemWithParam(people, 'names.first'.split('.'), 'Jane') // or
indexOfItemWithParam(people, ['names', 'first'], 'Jane')

最通用的方法不是采用属性路径,而是使用一个回调函数,您可以应用该函数来获取要比较的"属性"值。这也是本机数组迭代方法(如上面的reduce)的工作方式。使用例如findIndex,您根本不需要helper方法,只需调用即可

people.findIndex(function(item) { return item.names.first === 'Jane'; })

看起来您正在为JSON寻找类似xpath的语法(类似于JSON Path)。

试试goessner和这个JSONPath。