There isn't any need to reinvent the wheel loop, at least not explicitly.
Use some as it allows the browser to stop as soon as one element is found that matches:
if (vendors.some(e => e.Name === 'Magenic')) {
// We found at least one object that we're looking for!
}
or the equivalent (in this case) with find, which returns the found object instead of a boolean:
if (vendors.find(e => e.Name === 'Magenic')) {
// Usually the same result as above, but find returns the element itself
}
If you'd like to get the position of that element, use findIndex:
const i = vendors.findIndex(e => e.Name === 'Magenic');
if (i > -1) {
// We know that at least 1 object that matches has been found at the index i
}
If you need to get all of the objects that match:
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
// The same result as above, but filter returns all objects that match
}
If you need compatibility with really old browsers that don't support arrow functions, then your best bet is:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
// The same result as above, but filter returns all objects that match and we avoid an arrow function for compatibility
}
Answer from CAFxX on Stack OverflowThere isn't any need to reinvent the wheel loop, at least not explicitly.
Use some as it allows the browser to stop as soon as one element is found that matches:
if (vendors.some(e => e.Name === 'Magenic')) {
// We found at least one object that we're looking for!
}
or the equivalent (in this case) with find, which returns the found object instead of a boolean:
if (vendors.find(e => e.Name === 'Magenic')) {
// Usually the same result as above, but find returns the element itself
}
If you'd like to get the position of that element, use findIndex:
const i = vendors.findIndex(e => e.Name === 'Magenic');
if (i > -1) {
// We know that at least 1 object that matches has been found at the index i
}
If you need to get all of the objects that match:
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
// The same result as above, but filter returns all objects that match
}
If you need compatibility with really old browsers that don't support arrow functions, then your best bet is:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
// The same result as above, but filter returns all objects that match and we avoid an arrow function for compatibility
}
2018 edit: This answer is from 2011, before browsers had widely supported array filtering methods and arrow functions. Have a look at CAFxX's answer.
There is no "magic" way to check for something in an array without a loop. Even if you use some function, the function itself will use a loop. What you can do is break out of the loop as soon as you find what you're looking for to minimize computational time.
var found = false;
for(var i = 0; i < vendors.length; i++) {
if (vendors[i].Name == 'Magenic') {
found = true;
break;
}
}
Videos
It's true that object lookup occurs in constant time - O(1) - so using object properties instead of an array is one option, but if you're just trying to check whether a value is included in a collection, it would be more appropriate to use a Set, which is a (generally unordered) collection of values, which can also be looked up in linear time. (Using a plain object instead would require you to have values in addition to your keys, which you don't care about - so, use a Set instead.)
const set = new Set(['foo', 'bar']);
console.log(set.has('foo'));
console.log(set.has('baz'));
This will be useful when you have to look up multiple values for the same Set. But, adding items to the Set (just like adding properties to an object) is O(N), so if you're just going to look up a single value, once, there's no benefit to this nor the object technique, and you may as well just use an array includes test.
Updated 04/29/2020
As the commenter rightly pointed out it would seem V8 was optimizing out the array includes calls. An updated version that assigns to a var and uses it produces more expected results. In that case Object address is fastest, followed by Set has and in a distant third is Array includes (on my system / browser).
All the same, I do stand by my original point, that if making micro-optimizations it is worth testing assumptions. Just make sure your tests are valid ;)
Original
Well. Despite the obvious expectation that Object address and Set has should outperform Array includes, benchmarks against Chrome indicate that implementation trumps expectation.
In the benches I ran against Chrome Array includes was far and away the best performer.
I also tested locally with Node and got more expected results. In that Object address wins, followed closely by Set has, then Array includes was marginally slower than both.
Bottom line is, if you're making micro-optimizations (not recommending that) it's worth benchmarking rather than assuming which might be best for your particular case. Ultimately it comes down to the implementation, as your question implies. So optimizing for the target platform is key.
Here's the results I got:
Node (12.6.0):
ops for Object address 7804199
ops for Array includes 5200197
ops for Set has 7178483
Chrome (75.0):
https://jsbench.me/myjyq4ixs1/1

includes essentially checks if any element === the element you're searching for. In case of objects, === means literally the same object, as in the same reference (same place in memory), not the same shape.
var a1 = { name: 'a' }
var a2 = { name: 'a' }
console.log(a1 === a2) // false because they are not the same object in memory even if they have the same data
But if you search for an object that is actually in the array it works:
var a1 = { name: 'a' }
var a2 = { name: 'a' }
var array = [a1, a2]
console.log(array.includes(a1)) // true because the object pointed to by a1 is included in this array
Piping
let check = [{name: 'trent'}, {name: 'jason'}]
.map(item => item.name)
.includes('trent');
Simple & fast
let check = [{name: 'trent'}, {name: 'jason'}].some(el => el.name === 'trent')
Usesome method to check whether Capulet exists in an array:
let obj = { last: "Capulet" };
const isExist = whatIsInAName.some(f => f.last == obj.last)
const whatIsInAName = [
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
];
let obj = { last: "Capulet" };
const isExist = whatIsInAName.some(f => f.last == obj.last)
console.log(`Exists: ${isExist}`)
Or you can use filter to get all objects based on criteria:
const whatIsInAName = [
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
];
let obj = { last: "Capulet" };
const result = whatIsInAName.filter(f => f.last == obj.last);
console.log(result)
actually you can do a custom includes using some which will be faster than a map/filter
function whatIsInAName(arr, obj) {
return arr.some(({
last
}) => last === obj.last)
}
const testArray = [{
first: "Romeo",
last: "Montague"
},
{
first: "Mercutio",
last: null
},
{
first: "Tybalt",
last: "Capulet"
}
]
const testObj1 = {
last: "Capulet"
}
const testObj2 = {
last: "FOO"
}
const res1 = whatIsInAName(testArray, testObj1);
const res2 = whatIsInAName(testArray, testObj2);
console.log(res1);
console.log(res2);
Array.includes compares by object identity just like obj === obj2, so sadly this doesn't work unless the two items are references to the same object. You can often use Array.prototype.some() instead which takes a function:
const arr = [{a: 'b'}]
console.log(arr.some(item => item.a === 'b'))
But of course you then need to write a small function that defines what you mean by equality.
Its' because both of the objects are not the same. Both are stored at different place in memory and the equality operation results false.
But if you search for the same object, then it will return true.

Also, have a look at the below code, where you can understand that two identical objects also results false with the === operator.
For two objects to return true in ===, they should be pointing to same memory location.

You can turn the values of an Object into an array and test that a string is present. It assumes that the Object is not nested and the string is an exact match:
var obj = { a: 'test1', b: 'test2' };
if (Object.values(obj).indexOf('test1') > -1) {
console.log('has test1');
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
Shortest ES6+ one liner:
let exists = Object.values(obj).includes("test1");
Hei, just published chai-subset. Check this out: https://www.npmjs.org/package/chai-subset This should work for you)
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
var obj = {
a: 'b',
c: 'd',
e: {
foo: 'bar',
baz: {
qux: 'quux'
}
}
};
expect(obj).to.containSubset({
e: {
foo: 'bar',
baz: {
qux: 'quux'
}
}
});
The include and contain assertions can be used as either property based language chains or as methods to assert the inclusion of an object in an array or a substring in a string. When used as language chains, they toggle the contain flag for the keys assertion. [emphasis mine]
So if you're invoking include on an object (not an array or a string), then it only serves to toggle the contain flag for the keys assertion. By the looks of your example, testing for deep equality would make more sense, possibly checking for the key first.
origins.should.include.keys("otherObj");
origins.otherObj.should.deep.equal(match.otherObj);
Actually, now I browse the other examples, you would probably be happiest with this :
origins.should.have.deep.property("otherObj", match.otherObj)
does include works with array of objects?
Yes — if you use the same object as the argument to includes that's in the array:
const obj = {name: "Dan", id: 2};
const arr = [{name: "T.J.", id: 42}, obj, {name: "Joe", id: 3}];
console.log(arr.includes(obj)); // true
console.log(arr.includes({name: "Dan", id: 2})); // false
includes uses a === check, and o1 === o2 is only ever true when o1 and o2 refer to the same object. In your example, you're using two different but equivalent objects instead.
For your use case, you probably want some, which lets you execute a callback to determine whether an entry in the array matches a condition:
if (arr.some(e => e.id === 2)) {
Example:
const obj = {name: "Dan", id: 2};
const arr = [{name: "T.J.", id: 42}, obj, {name: "Joe", id: 3}];
console.log(arr.some(obj => obj.id === 2)); // true
There are various ways to spin that, depending on what you want the check to be (which are discussed at length in this question's answers), but that just means adjusting the contents of the function you pass some.
Not like that. Use some instead:
arr.some(obj => obj.id === 2)
Which checks if there is an object with id equals to 2.
If you are checking for both id and name then:
arr.some(obj => obj.id === 2 && obj.name === "Dan")
2022 UPDATE
Object.hasOwn()
Object.hasOwn()is recommended overObject.hasOwnProperty()because it works for objects created usingObject.create(null)and with objects that have overridden the inheritedhasOwnProperty()method. While it is possible to workaround these problems by callingObject.prototype.hasOwnProperty()on an external object,Object.hasOwn()is more intuitive.
Example
const object1 = {
prop: 'exists'
};
console.log(Object.hasOwn(object1, 'prop'));
// expected output: true
Original answer
I'm really confused by the answers that have been given - most of them are just outright incorrect. Of course you can have object properties that have undefined, null, or false values. So simply reducing the property check to typeof this[property] or, even worse, x.key will give you completely misleading results.
It depends on what you're looking for. If you want to know if an object physically contains a property (and it is not coming from somewhere up on the prototype chain) then object.hasOwnProperty is the way to go. All modern browsers support it. (It was missing in older versions of Safari - 2.0.1 and older - but those versions of the browser are rarely used any more.)
If what you're looking for is if an object has a property on it that is iterable (when you iterate over the properties of the object, it will appear) then doing: prop in object will give you your desired effect.
Since using hasOwnProperty is probably what you want, and considering that you may want a fallback method, I present to you the following solution:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
The above is a working, cross-browser, solution to hasOwnProperty(), with one caveat: It is unable to distinguish between cases where an identical property is on the prototype and on the instance - it just assumes that it's coming from the prototype. You could shift it to be more lenient or strict, based upon your situation, but at the very least this should be more helpful.
With Underscore.js or (even better) Lodash:
_.has(x, 'key');
Which calls Object.prototype.hasOwnProperty, but (a) is shorter to type, and (b) uses "a safe reference to hasOwnProperty" (i.e. it works even if hasOwnProperty is overwritten).
In particular, Lodash defines _.has as:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
2023 Update
As noted in John Resig's answer, this is now essentially built-in with Object.hasOwn. Lodash/underscore remain fallbacks for cases where Object.hasOwn is not available.