I'm using the filter() array helper going through some objects in an array. My idea is to create a dynamic filtering function to go through the objects in the array using bind(), but the arguments in bind are being used in a different way that I expected. Here's the code:
var products = [
{name:"lettuce", type:"vegetable"},
{name:"apple", type:"fruit"},
{name:"carrot", type:"vegetable"},
{name:"orange", type:"fruit"}
];
// this is the function used in filter()
function filterProducts(cat, product){
return product.type === cat;
}
// new array
var vegetables = products.filter(filterProducts.bind(products, "vegetable"));
I'm assuming that the filter helper is passing each object in the array after the arguments in the bind method, so first is the products which accounts for this
in the callback, then is the type I want to check on each object and finally the object itself.
The question is: Would you recommend doing it like this? I mean, could this be considered a good practice or would it be better to create a function to filter each type instead of doing it like this?
Consider using a factory function instead:
var products = [
{name:"lettuce", type:"vegetable"},
{name:"apple", type:"fruit"},
{name:"carrot", type:"vegetable"},
{name:"orange", type:"fruit"}
];
function filterProducts(category) {
// this is the function used in filter()
return function filter(product) {
return product.type === category;
};
}
// new array
var vegetables = products.filter(filterProducts("vegetable"));
console.log(vegetables);
I would recommend this pattern over using bind
, as it's a little easier to follow, at least in my opinion.
If you intend to use filterProducts
solely as a factory for Array#filter()
, then congratulations, you've finished reading this answer. If you're complaining that the following is "icky":
// product to be validated
var product = {name:"lettuce", type:"vegetable"};
// validate that product is a vegetable
if (filterProduct('vegetable')(product)) {
// code
}
Then keep reading.
Factory functions are good for defining a class of functions that differ by one or two key variables. In this case the key variable is category
. If you want a one-off function that looks nice in a single line of code, you're gonna be hard-pressed to find one unless you're a lodash
aficionado or something... but for this scenario, consider this instead of the above "icky" block of code:
// product to be validated
var product = {name:"lettuce", type:"vegetable"};
// vegetable validator
var isVegetable = filterProduct('vegetable');
// validate that product is a vegetable
if (isVegetable(product)) {
// code
}
Sure, bind
can be good in some situations, and I'm definitely not suggesting you avoid it at all costs, but you should first ask yourself whether it's really necessary or clean to use it before resorting to it.
This is really a matter of opinion. Some people use bind more than others. With es6 arrow notation, writing the function in the callback will prob be preferred over binding.
Only note I would make is that for clarity, when using bind,
var sayName = function(name){
console.log(name)
}
var sayTony = sayName.bind(null,'Tony')
It's best practice to put null
in as the first argument if it's not being used inside the function.
If you really value readability you can be more explicit and declare another function.
function filterProducts(cat, product){
return product.type === cat;
}
var filterVegtables = filterProducts.bind(null, 'vegtable');
then you can do
var vegetables = products.filter(filterVegtables);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With