7

I use the identity function in all my JavaScript programs:

function identity(value) {
    return value;
}

The reason is that I often need differentiate between primitives types (undefined, null, boolean, number and string) and object types (object and function) as returned by the typeof operator. I feel using the indentity function for this use case very succuint:

if (new identity(value) == value); // value is of an object type
if (new identity(value) != value); // value is of a primitive type

The identity function is much smaller and simpler than the following code:

function isObject(value) {
    var type = typeof value;
    return type == "object" || type == "function";
}

However on reading my code a friend of mine complained that my hack is misleading and more computationally expensive than the above alternative.

I don't want to remove this function from any of my programs as I believe it's an elegant hack. Then again I don't write programs solely for myself. Is there any other use case for the identity function in JavaScript?

4
  • 4
    Why not just use value === Object(value)? Or, for more readable code, define isObject to use it? Commented May 2, 2013 at 21:45
  • 2
    @Cory - I just wanted to find a practical use case for the identity function. I had too much time on my hands and so I worded this question interestingly to catch the attention of people and to not come across as a stupid idiot asking for a use case for the identity function. Commented May 4, 2013 at 12:31
  • 7
    One of the best uses is making code that may or may not apply a function work consistently: var func = optionalProcessFunc || identityFunc;. Now later on in the code, you don't need to know anything about how this section was configured to run. More generally, if you want to treat functions as monoids, it's convenient to use the identity function as mzero and compose as mconcat. Commented May 6, 2013 at 11:31
  • {x: 123} != {x:123} , objects by default are not equal in JS, cuz it have different reference. Why returning an object from identity function evaluates to true when comparing to that func itself ? I thougth constructor returns new object Commented Aug 14, 2020 at 18:42

3 Answers 3

25

IMHO:

new identity(value) == value

means absolutely nothing and without extra comment I would have to think for a while to figure out what the intent was. On the other hand:

isObject(value)

is obvious from the very beginning, no matter how it is implemented. Why can't you use your hack inside a function named isObject()?

BTW More suited for http://codereview.stackexchange.com.

Sign up to request clarification or add additional context in comments.

5 Comments

new identity(value) is a nice little hack. JavaScript engines only return the instance of a constructor if the constructor does not explicitly return an object (i.e. a value of the type object or function). Hence new identity(value) is always an object. Thus new identity(value) == value only returns true if value is an object. This is because the equality operators in JavaScript always check for identity when one of the operands is an object. Nice pun right?
@AaditMShah: I am really impressed (BTW using === might prove little faster) and I'm sure it works. What I mean is: no matter how fast it is, many people, including myself, will have no idea what it does. And (surprise!) you write software for people, not computers.
Yes. That is what my friend said too. Still when you are have some time off and have nothing better to do it's fun to see how you can use existing technology in weird and innovative ways.
BTW you are correct. Using strict equality does improve performance. Thank you.
Not to mention, it'd require that comment everywhere you used it. Putting aside the correctness issue that Kay discovered, I think the etiquette for this kind of thing should be -- if you're the sole maintainer, go for it. If you're on a team, isObject is the elegant choice: it self-documents, it hides its implementation, it doesn't require knowledge of Javascript's ugly parts. Are PHP's "variable variables" elegant?
14

I updated my "speedtest" to test if the right results are returned … they aren't:

If you compare with new identity(x) == x, then null is deemed an object. === works, though.

Such pitfalls speak in favor of the isObject(...) solution.

If you compare === 'object'/'function' in the isObject code, then it will be double as fast as your original implementation, and almost a third faster than new identity(x) === x.

1 Comment

The isObject(...) solution has the same pitfall, since typeof null === 'object'. Ironic.
1

Very late to the party on this one, but this thread is the top google result for 'javascript identity function' so I figured I'd chime in. I'm newish to Javascript, so hopefully I'm not simply unaware of a better solution.

I find this code useful:

function identity(a) { return a }
function makeCompare(key = identity, reverse = false) {
  function compareVals(a, b) { 
    const keyA = key(a);
    const keyB = key(b);
    let result =  keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
    if ( reverse ) { result *= -1 }
    return result;
  }
  return compareVals;
}

I can then sort arbitrary data structures in a tidy way:

const arrA = [ 1, 7 , 3];
console.log(arrA.sort( makeCompare() )) // uses the default identity() function as key
// output:
//  Array(3) [ 1, 3, 7 ]

const arrB = [ {name : "bob", age: 9}, {name : "alice", age: 7} ];
console.log(arrB.sort( makeCompare( val => { return val.age } )));
console.log(arrB.sort( makeCompare( val => { return val.age }, true)));
// output:
//  Array [Object { name: "alice", age: 7 }, Object { name: "bob", age: 9 }]
//  Array [Object { name: "bob", age: 9 }, Object { name: "alice", age: 7 }] 

Note that this is dependent on having an 'identity' function to use as the default 'key' function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.