0

I came across following (cleaned up) code and trying to understand what exactly is going on. I'm generally aware that bind function accepts this paramete, first parameter acts as argument etc. Also read the documents on mdn about how call/apply methods behave. However I'm having hard time understanding following syntax

var eObject = Object,
    DeObject_bind = eObject.bind,
    neObject_call = eObject.call,
    object_call = neObject_call.bind(DeObject_bind, neObject_call),
    reObject_apply = eObject.apply,
    object_apply = object_call(reObject_apply)

What exactly is happening here? For example it seems like object_call is bound with this set to Object.bind. What does this achieve? Same for apply - what exactly is happening?

user871199
  • 1,420
  • 19
  • 28
  • 1
    If you found this code without an accompanying thorough explanation, you may want to look for better sources. – Pointy Jul 12 '23 at 21:43
  • @Pointy, some javascript code is intentionally obfuscated and employees the techniques discussed here. They are not going to put comments in the code, however as a developer, I want to understand what exactly is going on. – user871199 Jul 12 '23 at 21:56
  • 1
    Well it's not really obfuscated; those are perfectly readable function calls with fairly clear names for variables and functions. The issue is that it's creating shorthand bound functions that can do things that are academically interesting, but not really practically useful. – Pointy Jul 12 '23 at 22:26
  • Starting with `eObject = Object` is weird. One would have expected `eObject = Function.prototype` – Bergi Jul 12 '23 at 22:30
  • @Bergi the code is just looking for a shortcut to `Function.prototype.bind` and `Function.prototype.call`. – Pointy Jul 12 '23 at 22:33
  • @Pointy Yes, but still why start at `Object`? They could at least have used `Function.call` and `Function.bind` – Bergi Jul 12 '23 at 22:36
  • Probably related: [How does Function.bind.bind(Function.call) uncurry?](https://stackoverflow.com/q/23482982/1048572) and [Chaining 'bind' and 'call' in JavaScript?](https://stackoverflow.com/q/31198503/1048572) - but `call.bind(bind, call)(apply)` is a step weirder – Bergi Jul 12 '23 at 22:37
  • @Bergi who knows what sort of twisted logic drives the authors of stuff like this? – Pointy Jul 12 '23 at 22:46
  • If it helps, the my cleaned up code snippets came from what seems to be browser fingerprinting library. I am curious about what kind of information is collected from these scripts. One example is at https://login.xfinity.com/login, comcast_common.js. I've seen such scripts on many websites. You can check the source directly – user871199 Jul 12 '23 at 22:54

1 Answers1

0

First, I'm going to abbreviate those long variable names (the first two) as simply bind and call, because that's what they are.

Thus neObject_call.bind(DeObject_bind, neObject_call) is better written as

call.bind(bind, call)

meaning that we'll get a bound function that will be a shorthand for bind.call(call) with optional extra parameters. Why? Well, call.bind(bind) will bind the bind function itself as the this value in a call to the call function, as if we were doing bind.call(). Generally, to use call you take some random function fn and write fn.call(someThis, someValue). So binding call to bind makes a shorthand function for bind.call().

Thus object_call(reObject_apply) is basically

bind.call(call, apply)

That calls bind with call as the this value, so it's like

call.bind(apply)

which makes a bound version of call with apply as the this value. That, then is like

apply.call(...)

That lets you call apply() "naked" instead of someFn.apply(), instead allowing you to pass the function as the first parameter.

Why would anybody do this? Well, it might be useful to have versions of those meta-functions that can easily be used in things like .map() or .reduce(), I guess.

Pointy
  • 405,095
  • 59
  • 585
  • 614