Understanding the declaration of the underscore in

2019-05-13 21:58发布

问题:

This is from the beginning of the annotated source of _.js. Try though I may, my JavaScript abilities are not at a high enough level to understand what's going on here. I'm hoping someone can give a real step by step explanation. I really have literally no idea what the code below does besides somehow setting up the _ for use, despite that I understand each individual expression.

 var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
  };

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else {
    root._ = _;
  }

回答1:

var _ = function(obj) {
    // Either serve as the identity function on `_` instances,
    // ... or instantiate a new `_` object for other input.

    // If an `_` instance was passed, return it.
    if (obj instanceof _) return obj;
    // If someone called `_(...)`, rather than `new _(...)`,
    // ... return `new _(...)` to instantiate an instance.
    if (!(this instanceof _)) return new _(obj);

    // If we are instantiating a new `_` object with an underlying,
    // ... object, set that object to the `_wrapped` property.
    this._wrapped = obj;
};

// If there is an exports value (for modularity)...
if (typeof exports !== 'undefined') {
    // If we're in Node.js with module.exports...
    if (typeof module !== 'undefined' && module.exports) {
        // Set the export to `_`
        exports = module.exports = _;
    }
    // Export `_` as `_`
    exports._ = _;
} else {
    // Otherwise, set `_` on the global object, as set at the beginning
    // ... via `(function(){ var root = this; /* ... */ }())`
    root._ = _;
}


回答2:

Well, the lower snippet is quite unrelated. Basically it's exporting the _ from the closure to the global scope, or using a module definition system if available. No great deal, and nothing to care about if you don't use modules.

The _ function shouldn't be that hard to understand. You need to know

  • What is the underscore function for?
  • What does the new operator do?
  • How does the instanceof operator work?

So what it does:

  1. If the argument is an Underscore instance, return it unchanged.
  2. If the function is not called as a constructor (when the this context is not an Underscore instance) then do so and return that
  3. Else wrap the argument in the current instance