1

The following is unintuitive behavior in javascript,

function function1 () {};
function function2 () {};

var class_a_functions = {function1:true, function2:true};
var contained = function1 in class_a_functions;//false
var equals = function1.name in class_a_functions;//true

Why does the in containment test fail even though I have inserted the functions, not their names, into the dictionary?

EDIT: If it isn't obvious, I am aware that function1.name is "function1". This is why I asked why the test fails "even though I have inserted the functions, not their names".

ealfonso
  • 6,622
  • 5
  • 39
  • 67
  • that is `function` not `fuction`? – Mritunjay Aug 08 '14 at 04:46
  • should be var contained = 'function1' in class_a_functions; or contained = function1.name in class_a_function – dandavis Aug 08 '14 at 04:56
  • that's exactly why I am asking the question. also note that function.name isn't supported in IE. – ealfonso Aug 08 '14 at 04:57
  • 1
    You can't use a function as an object key (if that's what you're trying to illustrate). Object keys are strings only. There is an object that lets you keep track of a set of other objects (which could be functions too) here: https://github.com/jfriend00/Javascript-Set. It does that by automatically coining a unique string as a key property for each object and using that key in the ObjectSet. – jfriend00 Aug 08 '14 at 05:23
  • You haven't "inserted the functions". First, unlike python, in JS `{ key: value }` syntax treats `key` as literal "key". You'd need `{ [function1]: true }` syntax for a dynamic key. BUT JS objects coerce all keys to strings anyway! Play with `[ function1, function2 ]` for a container actually holding functions. – Beni Cherniavsky-Paskin Jul 10 '23 at 10:16

5 Answers5

3

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

// Arrays
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // returns true
3 in trees        // returns true
6 in trees        // returns false cause there's no 6th key in trees Array
"bay" in trees    // returns false (you must specify the 
                  // index number, not the value at that index)
"length" in trees // returns true (length is an Array property)

That's why it returns false

On the other case, class_a_functions[0] is the reference to the stored function in Array that's why equality returns true cause fn1() === fn1()


Now after your edited question the above seems like nonsense so I'll answer further:

var class_a_functions = {function1:true, function2:true};

Is now and object where function1 and function2 are simple Properties holding true as Value.


var contained = function1 in class_a_functions;//false

The above returns false cause there's no "function1" Function inside the Object reference class_a_functions


var equals = function1.name in class_a_functions;//true

The above... well, let's go back to MDN, says:

Summary:
The in operator returns true if the specified property
is in the specified object.

So you have a property of function1 Now let's see if is present in the Object class_a_functions ... Yes. So TRUE

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • 1
    @erjoalgo - He's showing that `in` applies to array indexes, not to contents of the array. A few more words of text would improve the answer. – jfriend00 Aug 08 '14 at 04:50
  • Ok. I need to rephrase the question then, sorry – ealfonso Aug 08 '14 at 04:50
  • This has a lot to do with the question. First read the linked Document then notice how `IN` is actually working – Hanky Panky Aug 08 '14 at 04:51
  • ok. So I was the one to make the mistake, thinking that I could describe the problem more simply with an array instead of a dictionary. – ealfonso Aug 08 '14 at 04:53
  • I see. Is there a way to have something like a set of objects by object id or memory location in javascript? – ealfonso Aug 08 '14 at 04:56
  • 1
    @erjoalgo - here's an ObjectSet if that's really what you're looking for: https://github.com/jfriend00/Javascript-Set – jfriend00 Aug 08 '14 at 05:23
  • I accepted your question. But most of your commentary is trivial and restates information that the OP (I) evidently already knows. – ealfonso Aug 08 '14 at 05:23
1

I'm not sure why most of the answers are so trivial and don't really address the underlying issue motivating the question, which is that getting the memory address/object hash/object id in javascipt is "impossible", and therefore the equality testing by object reference is also "impossible".

How can I get the memory address of a JavaScript variable?

A solution for that containment problem is to monkey-patch an object to contain a unique property/string that can be used as a key.

Community
  • 1
  • 1
ealfonso
  • 6,622
  • 5
  • 39
  • 67
0

The in is used to identify the key not the value.

GramThanos
  • 3,572
  • 1
  • 22
  • 34
0

The in operator tests if a property is in an object. function1 is not a property of the array, it's a member.

Mark
  • 90,562
  • 7
  • 108
  • 148
0

There should be

'function1' in class_a_functions;//true

This is because

In a dictionary

obj = {key:5}

this is equal to

obj = {"key":5} // so it will be stored as string

If you will see the docs it says prop is A string or numeric expression representing a property name or array index.

Mritunjay
  • 25,338
  • 7
  • 55
  • 68