This is the code I get, but I don't know this two lines means:
o[arr[i]] = o[arr[i]] || {};
o = o[arr[i]];
Full code:
var GLOBAL={};
GLOBAL.namespace=function(str){
var arr = str.split("."), o=GLOBAL;
for(i=(arr[0]=="GLOBAL") ? 1 : 0; i<arr.length; i++){
o[arr[i]] = o[arr[i]] || {};
o = o[arr[i]];
}
};
GLOBAL.namespace("A.Dog");
// GLOBAL.A = {};
// GLOBAL.A.Dog = {};
GLOBAL.A.Dog.name = "diudiu";
alert(GLOBAL.A.Dog.name)
There are two statements:
This:
o[arr[i]] = o[arr[i]] || {};
And:
o = o[arr[i]];
The second sets the nested object o
to its key arr[i]
, overwriting itself with one of it's own key/values.
The first set's the o
object's key arr[i]
to itself or an empty object. The ||
operator is a boolean or and will only trigger the {}
if o[arr[i]]
evaluates to false.
This kind of statement is often used to intialize a variable (eg in the global namespace) when you don't know if it's already been initialized (so you don't overwrite it).
Break it down step-by-step to make is clearer:
o[arr[i]] = o[arr[i]] || {};
is the same as:
var x = arr[i];
o[x] = o[x] || {};
is the same as:
var x = arr[i];
if (o[x] == undefined) {
o[x] = {};
}
The pattern A = B || DEFAULT_VALUE
A = B || DEFAULT_VALUE
is an idiom which uses the short-circuiting nature of the ||
operator. In javascript, the ||
operator does not return true
or false
but instead it returns the first non-false value or false
. So if the first variable is not falsy it evaluates to the value of the first variable otherwise it evaluates to the value of the second variable.
The first line ensures that o[arr[i]]
is defined. It either sets o[arr[i]]
to itself if it was previously created, or a new object (ie {}
) if o[arr[i]]
is undefined.
The second line assigns the object from the first line to o
so that the namespace traversal can continue.
The function GLOBAL.namespace(str)
is used to create a namespace (and its sub-namespaces) if it doesn't already exist.
Here is how it works:
It splits up str
by periods into sub-namespaces:
arr = str.split(".")
It sets o
to the global namespace:
o=GLOBAL
It skips the first sub-namespace if the first sub-namespace is GLOBAL
:
(arr[0]=="GLOBAL") ? 1 : 0
For each sub-namespace in arr
:
It checks if it exists under o
, and if it doesn't, it creates it:
o[arr[i]] = o[arr[i]] || {};
It sets up o
to work one level deeper, so it can work on the next sub-namespace:
o = o[arr[i]];
For purposes of understanding the function, here's a version with the purpose of each variable spelled out, and steps split up a bit more:
var GLOBAL={};
GLOBAL.namespace=function(fullNamespaceName){
var namespaceNames = fullNamespaceName.split("."); // arr
var currentNamespace=GLOBAL; // o
var currentIndex = (namespaceNames[0]=="GLOBAL") ? 1 : 0; // i
for(; currentIndex<namespaces.length; currentIndex++){
var subNamespaceName = namespaceNames[currentIndex];
var subNamespace = currentNamespace[subNamespaceName];
subNamespace = subNamespace || {};
currentNamespace[subNamespaceName] = subNamespace;
currentNamespace = subNamespace;
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.