Antonio Pavicevac-Ortiz
Antonio Pavicevac-Ortiz

Reputation: 7739

Unexpected results from the Underscore.js _.where method

From the documentation of Underscore.js

_.where(list, properties);

Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties.

Essentially you give it an object as the list, and pass 'key-value pairs' as the properties. Those 'key-value pairs/properties' are the markers you use to tell where as what to pull out and return.

That being said, I tried the following:

var obj = {
    innerObj1 : { 
                  speak: function(){console.log('My name is ' + name);}, 
                  name: "Tiger", 
                  space: 7
                }, 
    innerObj2 : {
                  speak: function(){console.log('My name is ' + name);}, 
                  name: "Tiger2", 
                  space: 1
                }, 
    innerOnj3 : {
                  speak: function(){console.log('My name is ' + name);}, 
                  name: "Tiger3", 
                  space: 3}, 
    innerObj4 : {
                 speak: function(){console.log('My name is ' + name);}, 
                 name: "Tiger4", 
                 space: 3}
};

This returns:

_.where(obj,{speak:function(){console.log('My name is ' + name);}});
[] //returns a empty array, WHAT?!

vs.

function speak(){console.log('My name is ' + name);}



var obj = {
    innerObj1 : { 
                  speak: speak, 
                  name: "Tiger", 
                  space: 7
                }, 
    innerObj2 : {
                  speak: speak, 
                  name: "Tiger2", 
                  space: 1
                }, 
    innerOnj3 : {
                  speak: speak, 
                  name: "Tiger3", 
                  space: 3}, 
    innerObj4 : {
                  speak: speak, 
                 name: "Tiger4", 
                 space: 3}
};


_.where(obj,{speak:speak});

This will return:

[Objectname: "Tiger"space: 7speak: speak()__proto__: Object, Objectname: "Tiger2"space: 1speak: speak()__proto__: Object, Objectname: "Tiger3"space: 3speak: speak()__proto__: Object, Objectname: "Tiger4"space: 3speak: speak()__proto__: Object]

That is where my befuddlement lies. Why would the first method just return an empty object, but second method returns what you would expect...

I am aware of this question but it didn't help with my confusion... Thank you in advance!

Upvotes: 1

Views: 99

Answers (1)

Omri Aharon
Omri Aharon

Reputation: 17064

That's actually a pretty well expected result.

You see, on your first example, you create a new function for each object, so that:

innerObj1.speak !== innerObj2.speak. The function may appear to be the same, but it's a different object. Not only that all speak values are different from each other, they're also different from the (also new!) function you pass as a value in the _.where() function.

On the 2nd example, you define one function and reference that from each object so now innerObj1.speak === innerObj2.speak, since all speak properties reference the same function.

Take a look: Fiddle

Upvotes: 2

Related Questions