Reputation:
I have come across this while going through underscore js source code.
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
this ||
{};
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
What is that root._
does here?
Upvotes: 1
Views: 4257
Reputation: 370819
In general, that block of code will result in previousUnderscore
refering to the _
property on self
, or on global
, or on this
(whichever object root
evaluated to), and said property value may not exist. It's no different from any other property name.
For example, if the first condition passes:
typeof self == 'object' && self.self === self && self
then if self
has a _
property which contains 'foo'
, then previousUnderscore
will be assigned that same string, 'foo'
.
const self = {
_: 'foo'
};
self.self = self;
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
this ||
{};
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
console.log(previousUnderscore, typeof previousUnderscore);
If self
did not have the _
property, then previousUnderscore
would be undefined
.
The exact same logic applies to any other property name, for example:
const self = {
somePropName: 'foo'
};
self.self = self;
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
this ||
{};
// Save the previous value of the `_` variable.
var previousUnderscore = root.somePropName;
console.log(previousUnderscore, typeof previousUnderscore);
In particular, for underscore.js, what this code is doing is it
(1) determines which object should be used for the root
variable name
(2) saves the _
property in that object in the variable name previousUnderscore
, so that when underscore.js reassigns root._
, one can then call noConflict
to
Give control of the
_
variable back to its previous owner
by running the following line:
root._ = previousUnderscore;
For example, if you ran underscore.js and previously had _
on the global object (say, Lodash), _
would then refer to the Underscore object - but if you called noConflict
, then _
would refer back to whatever it originally referred to (such as Lodash).
// Underscore runs after Lodash, so when the JS here runs initially,
// _ refers to Underscore, but Underscore has saved a reference to the previous _,
// which was Lodash,
// in the variable name previousUnderscore that your question is asking about:
// Underscore function - give _ back to Lodash:
_.noConflict();
// Lodash function:
_.noop()
console.log('done');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
Upvotes: 2