I'm not sure what this construct means but I've seen it a few times. The example below is from another Stack Overflow question. I'm not sure how to interpret the initial "or" construct itself:
Object.keys = Object.keys || (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
DontEnums = [
'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
],
DontEnumsLength = DontEnums.length;
//etc...
});
Named functions can be either declared in a statement or used in an expression. Named function expressions create readable stack traces. The name of the function is bound inside its body, and that can be useful. And we can use the name to have a function invoke itself, or to access its properties like any other object.
The logical OR ( || ) operator (logical disjunction) for a set of operands is true if and only if one or more of its operands is true. It is typically used with boolean (logical) values. When it is, it returns a Boolean value.
The assignment expression y = x = f() starts to evaluate. The y on this assignment's left-hand side evaluates into a reference to the variable named y . The assignment expression x = f() starts to evaluate. The x on this assignment's left-hand side evaluates into a reference to the variable named x .
a = a || function(){...}
is an idiom that is very common in Javascript. It relies on two concepts that, while not unique to Javascript, you might not yet be familiar with.
Operator short circuiting[wikipedia] is a compiler optimization that was invented to prevent unnecessary evaluation.
To demonstrate this, let us suppose that we want to determine whether a person is a teenager: that is, whether a person has an age inclusively between 13 and 19 years.
var isTeenager = person.age >= 13 && person.age <= 19;
Now, let us suppose that the code executes and it turns out that the person is younger than 13. The first condition will be evaluated and will return false. Since the program now knows that the the left hand side of the &&
operator is false
, and since &&
requires both sides to be true
in order to evaluate to true
, it knows that evaluating the right hand side is pointless.
In other words, the program, having seen that the person's age is not greater than 13, already knows that he is not a teenager and couldn't care less whether or not he is less than 19.
The same sort of principle applies to the ||
operator. Suppose we wanted to know if a person can ride the bus for free: that is, if the person is over 70 years old or is handicapped.
var canRideFree = person.age >= 70 || isHandicapped(person);
If the person is over 70, the program already knows that he can ride free. At this point, the program does not care if he is handicapped or not and thus does not evaluate the call to the isHandicapped
function. If, on the other hand, the person was younger than 70, then canRideFree
would be set to whatever isHandicapped
returns.
Truthy and falsy values[some random person's blog] are the boolean evaluations of objects. In Javascript, every object will evaluate to either a "truthy" or a "falsy" value.
An expression is "falsy" if its value is any of these:
false, null, undefined, 0, "", NaN
Everything else is truthy.
People take advantage of the fact that a null or undefined variable evaluates to false
. This means that you can check if a variable exists very easily:
if (a) { /* a exists and is not a falsy value */ }
The ||
operator short circuits and returns the value of the last expression that it evaluates. This principle combines with truthiness in this single statement:
Object.keys = Object.keys || function() {...}
If Object.keys
is truthy, it will be evaluated and assigned to itself. Otherwise, Object.keys
will be assigned to the function. This is a very common idiom in Javascript for checking if a value already exists and assigning it to something else if it doesn't.
Some other languages, such as C#, that do not have truthiness, have a null-coalescing operator[MSDN] that has a similar purpose.
object Value = PossiblyNullValue ?? ValueIfNull;
In this code, Value
will be assigned to PossiblyNullValue
, unless it's null, in which case it will be assigned to ValueIfNull
.
If you didn't bother to read anything I said above, all you need to know is that a = a || function() {...}
basically does what this code does:
if (exists(Object.keys)) {
Object.keys = Object.keys;
} else {
Object.keys = function() {...};
}
function exists(obj) {
return typeof obj !== "undefined" &&
obj !== null &&
obj !== false &&
obj !== 0 &&
obj !== "" &&
!isNaN(obj);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With