基于JavaScript实现前端数据多条件动态筛选功能
本文介绍一种基于JavaScript的前端数据多条件筛选方案。通过封装Array.prototype.filter,将筛选逻辑划分为区间类型(rangesFilter)与选择类型(choosesFilter)两大模块。该方案支持根据数据字段动态配置筛选条件,实现多条件组合筛选,并具备较好的扩展性与可维护性,适用于电商列表等复杂交互场景。
前端数据多条件筛选方案概述
在前端开发中,有时需要直接对数据进行筛选处理,以提升用户的交互体验。当可用的筛选维度较多时,如果将筛选逻辑硬编码,会给后续的维护工作带来巨大负担。为此,本文分享一个轻量级的筛选器实现思路,其筛选规则可根据数据中存在的字段进行动态配置。
参考京东等主流电商平台的筛选交互,本文选取“价格区间”和“品牌”作为示例测试数据。

核心代码实现如下。
核心筛选逻辑与数据结构
该方案主要依赖JavaScript原生提供的Array.prototype.filter方法。该方法会遍历数组中的每个元素,检查其是否满足指定条件,并返回一个包含符合条件元素的新数组,原数组保持不变。
// filter()
var foo = [0,1,2,3,4,5,6,7,8,9];
var foo1 = foo.filter(
function(item) {
return item >= 5
}
);
console.log(foo1); // [5, 6, 7, 8, 9]
利用这一特性,筛选数据变得十分便捷。首先,我们需要定义一个商品数据结构。
// 定义商品类
function Product(name, brand, price) {
this.name = name; // 名称
this.brand = brand; // 品牌
this.price = price; // 价格
}
接着,构建一个过滤器对象,将所有具体的过滤逻辑封装其中。为了实现自动适配不同的筛选场景,我们将筛选条件划分为两类:一类是区间类型(rangesFilter),适用于品牌、内存等范围判断;另一类是选择类型(choosesFilter),适用于价格、屏幕尺寸等具体选项。
当多个大类条件同时生效时,执行的是“与”逻辑,即每个大类基于上一类的筛选结果继续筛选。例如,若要筛选价格在2000至5000元之间的华为手机,首先调用rangesFilter处理products得到中间结果result1,随后再使用choosesFilter对result1进行筛选,最终得到结果resulte2。
若存在其他未定义的大类筛选逻辑,需另行扩展处理。
// 商品筛选器
const ProductFilters = {
/**
* 区间类型筛选
* @param {array<Product>} products
* @param {array<{type: String, low: number, high: number}>} ranges
*/
rangesFilter: function (products, ranges) { }
/**
* 选择类型筛选
* @param {array<Product>} products
* @param {array<{type: String, value: String}>} chooses
*/
choosesFilter: function (products, chooses) { }
}
区间与选择类型筛选实现
区间类型筛选的具体实现代码如下。
// 区间类型条件结构
ranges: [
{
type: 'price', // 筛选类型/字段
low: 3000, // 最小值
high: 6000 // 最大值
}
]
/**
* @param {array<Product>} products
* @param {array<{type: String, low: number, high: number}>} ranges
*/
rangesFilter: function (products, ranges) {
if (ranges.length === 0) {
return products;
} else {
/**
* 循环多个区间条件,
* 每种区间类型应该只有一个,
* 比如价格区间不会有1000-2000和4000-6000同时需要的情况
*/
for (let range of ranges) {
// 多个不同类型区间是与逻辑,可以直接赋值给自身
products = products.filter(function (item) {
return item[range.type] >= range.low && item[range.type] <= range.high;
});
}
return products;
}
}
选择类型筛选的实现逻辑如下。
// 选择类型条件结构
chooses: [
{
type: 'brand',
value: '华为'
},
{
type: 'brand',
value: '苹果'
}
]
/**
* @param {array<Product>} products
* @param {array<{type: String, value: String}>} chooses
*/
choosesFilter: function (products, chooses) {
let tmpProducts = [];
if (chooses.length === 0) {
tmpProducts = products;
} else {
/**
* 选择类型条件是或逻辑,使用数组连接concat
*/
for (let choice of chooses) {
tmpProducts = tmpProducts.concat(products.filter(function (item) {
return item[choice.type].indexOf(choice.value) !== -1;
}));
}
}
return tmpProducts;
}
定义一个统一执行函数doFilter(),用于协调各筛选模块。
function doFilter(products, conditions) {
// 根据条件循环调用筛选器里的方法
for (key in conditions) {
// 判断是否有需要的过滤方法
if (ProductFilters.hasOwnProperty(key + 'Filter') && typeof ProductFilters[key + 'Filter'] === 'function') {
products = ProductFilters[key + 'Filter'](products, Conditions[key]);
}
}
return products;
}
// 将两种大类的筛选条件放在同一个对象里
let Conditions = {
ranges: [
{
type: 'price',
low: 3000,
high: 6000
}
],
chooses: [
{
type: 'brand',
value: '华为'
}
]
}
测试用例与结果验证
接下来进行功能测试。
构造包含10个商品的数据集,并预设相应的筛选条件。
// 商品数组
const products = [
new Product('华为荣耀9', '华为', 2299),
new Product('华为P10', '华为', 3488),
new Product('小米MIX2', '小米', 3599),
new Product('小米6', '小米', 2499),
new Product('小米Note3', '小米', 2499),
new Product('iPhone7 32G', '苹果', 4588),
new Product('iPhone7 Plus 128G', '苹果', 6388),
new Product('iPhone8', '苹果', 5888),
new Product('三星Galaxy S8', '三星', 5688),
new Product('三星Galaxy S7 edge', '三星', 3399),
];
// 筛选条件
let Conditions = {
ranges: [
{
type: 'price',
low: 3000,
high: 6000
}
],
chooses: [
{
type: 'brand',
value: '华为'
},
{
type: 'brand',
value: '苹果'
}
]
}
调用上述定义的筛选函数。
let result = doFilter(products, Conditions);
console.log(result);
查看控制台输出结果。

扩展性与优化建议
该代码具备良好的扩展性和可维护性。只要确保筛选条件中的type字段与商品数据中的字段名一致,即可实现筛选。例如,若将筛选条件配置调整为其他结构,只要type匹配,逻辑依然生效。
let Conditions = {
ranges: [
{
type: 'price',
low: 3000,
high: 6000
}
],
chooses: [
{
type: 'name',
value: 'iPhone'
}
]
}
再次查看调整后的输出结果。

此外,搜索匹配等功能仍有优化空间,例如是否区分大小写、是完全匹配还是模糊匹配等细节,可根据实际需求进一步完善。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
JavaScript异步发送HTTP请求时怎么优雅地处理错误
2026-11-05 17:10:44
5款主流JS在线运行工具对比:CodePen、JSFiddle与StackBlitz怎么选
2026-11-05 17:04:04
JavaScript入门书籍避坑:这些书不适合初学者
2026-11-05 16:31:15
JS使用Math.round实现保留两位小数的原理与代码
2026-11-05 15:35:55
JavaScript 原生 Date 对象怎么实现日期加减
2026-11-05 14:30:00
