3

I'm new to JS and i'm Currently reading 'this & Object Prototypes' of the greate 'You Don't Know JS' book series. In Chapter 2 (Softening Binding):

if (!Function.prototype.softBind) {
    Function.prototype.softBind = function(obj) {
        var fn = this,
            curried = [].slice.call( arguments, 1 ),
            bound = function bound() {
                return fn.apply(
                    (!this ||
                        (typeof window !== "undefined" &&
                            this === window) ||
                        (typeof global !== "undefined" &&
                            this === global)
                    ) ? obj : this,
                    curried.concat.apply( curried, arguments )
                );
            };
        bound.prototype = Object.create( fn.prototype );
        return bound;
    };
}
I dont understand:

(!this || (typeof window !== "undefined" && this === window) || (typeof global !== "undefined"  && this === global)
specially the '!this'

Thanks

Priya
  • 1,359
  • 6
  • 21
  • 41
Kas
  • 67
  • 3

1 Answers1

4

So, first recall what .apply does:

The apply() method calls a function with a given this value and arguments provided as an array (or an array-like object).

So, the code you're interested in is being passed as the first argument to apply, which means it should return some value of this, or something that it call pull a this from. Let's break it down:

(
  !this ||
  (typeof window !== "undefined" && this === window) || 
  (typeof global !== "undefined" && this === global)
)

First, why do we need to compare against undefined when checking the window/global objects? Because that's what typeof will return when a comparison against them is false.

Now, to understand the code better, you could easily rewrite the above like this:

if (!this) {
  // If the local 'this' is a falsey value
  return obj;
} else if (typeof window !== "undefined" && this === window) {
  // If window is defined and 'this' is referencing it
  return obj;
} else if (typeof global !== "undefined" && this === global) {
  // If global is defined and 'this' is referencing it
  return obj;
} else {
  return this;
}

So, basically, what all that is doing saying is: if the local this context is a falsey value or if it points to either the special window and/or global objects, pull the this context from the passed in obj. Otherwise, use the local this context.

Community
  • 1
  • 1
Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128