This question already has answers here:
How does this JavaScript/jQuery syntax work: (function( window, undefined ) { })(window)?
(5 answers)
Closed 10 years ago.
In following code of jQuery, why next parameter is undefined
JavaScript:
(function(a,b){
....
})(window)
Here a=window but b=undefined, why is so?
That's a common technique to assure you have a true undefined value to check against since the undefined property of the window object used to be writeable and thus could not reliably be used in checks. Since only one parameter is handed over to the function, the second one is assured to be undefined. The name of that variable does not matter, it could be undefined but as well foobar or, as in this case, (because this is the shortest possible way saving valuable bytes) b.
Now you can safely check for undefinedness of variables, because you are sure about the value of b:
// overwriting the global undefined property works in old browsers
undefined = 3;
(function(a,b){
var asd; // not initialised, thus undefined
if (asd === undefined){
// should trigger, but won't because undefined has been overwritten to 3
}
if (asd === b){
// is safe, bcause you know that b is undefined
}
})(window)
New browsers (IE9, FF4+, Chrome) obey the EcmaScript5 specification and undefined is not writable any more.
Because you are not passing anything for the second parameter. You are passing just one, namely window.
Your code
(function(a,b){
....
})(window)
defines a function and calls it immediately. The last line above actually calls the function using the window parameter. If you pass 2 parameters there, b will not be undefined.
This is immediate javascript function syntax you're trying to use:
(/* function body */)(/* params */)
Named function defined like:
function addNumbers(a, b){
alert(a + b);
}
You call it:
addNumbers(1, 2)
Or similar immediate function (defined and executed at the same time):
(function(a, b){
alert(a + b);
})(1, 2)
Related
From this question, given that I don't want to specify any context, hence, passing null to thisArg in call().
What would be the difference between line 2 and line 3 in the following code? Is there any benefit from doing one over the other?
function sum(a,b) { return a + b; }
var result1 = sum.call(null,3,4); // 7
var result2 = sum(3,4); // 7
Similarly for apply():
var arr = [1,2,4];
var result3 = Math.max.apply(null, arr); // 4
var result4 = Math.max(...arr); // 4
It depends on whether the function you're calling was defined in loose mode or strict mode.
When calling a loose-mode function, the following three things all call the function such that this within the call is the global object for the environment (globalThis, aka window on browsers):
Calling the function without setting this: fn()
Calling the function providing a this value of undefined: fn.call(undefined) and similar
Calling the function providing a this value of null: fn.call(null) and similar
With a strict mode function, the first two both cause this during the call to be undefined, and the third (explicitly setting it to null) sets it to (you guessed it) null.
Examples:
function loose() {
console.log(`loose: ${this === null ? "null" : typeof this}`);
}
loose();
loose.call(undefined);
loose.call(null);
function strict() {
"use strict";
console.log(`strict: ${this === null ? "null" : typeof this}`);
}
strict();
strict.call(undefined);
strict.call(null);
In the normal case, if you don't need to set this to anything in particular, just call the function so the default behavior takes place.
One wrinkle: If you have an array of arguments you need to spread out as discrete arguments to the function, in any even vaguely up-to-date environment, you can use spread notation to do that: fn(...theArray). If you're stuck in an obsolete environment, the rough equivalent is fn.apply(undefined, theArray).
If you have a specific need to set a specific this value, you can do that via call or apply (as you've found), including (for strict mode functions) undefined or null.
TJ Crowder has the detailed response here, but as a general rule:
fn.call(null): In almost all cases, just call the function.
fn.apply(null, args): This is useful in some cases where you have an array of arguments and your environment doesn't support ...args, but otherwise spreading the arguments is probably more conventional: fn(...args)
Could you please point me to the nice way of skipping optional parameters in JavaScript.
For example, I want to throw away all opt_ parameters here:
goog.net.XhrIo.send(url, opt_callback, opt_method, opt_content, {'Cache-Control': 'no-cache'}, opt_timeoutInterval)
Solution:
goog.net.XhrIo.send(url, undefined, undefined, undefined, {'Cache-Control': 'no-cache'})
You should use undefined instead of optional parameter you want to skip, because this 100% simulates the default value for optional parameters in JavaScript.
Small example:
myfunc(param);
//is equivalent to
myfunc(param, undefined, undefined, undefined);
Strong recommendation: use JSON if you have a lot of parameters, and you can have optional parameters in the middle of the parameters list. Look how this is done in jQuery.
Short answer
The safest bet is undefined, and should work almost ubiquitously. Ultimately, though, you cannot trick the function being called into thinking you truly omitted a parameter.
If you find yourself leaning towards using null just because it's shorter, consider declaring a variable named _ as a nice shorthand for undefined:
(function() { // First line of every script file
"use strict";
var _ = undefined; // For shorthand
// ...
aFunction(a, _, c);
// ...
})(); // Last line of every script
Details
First, know that:
typeof undefined evaluates to "undefined"
typeof null evaluates to "object"
So suppose a function takes an argument that it expects to be of type "number". If you provide null as a value, you're giving it an "object". The semantics are off.1
As developers continue to write increasingly robust javascript code, there's an increasing chance that the functions you call explicitly check a parameter's value for undefined as opposed to the classic if (aParam) {...}. You'll be on shaky ground if you continue to use null interchangeably with undefined just because they both happen to coerce to false.
Be aware, though, that it is in fact possible for a function to tell if a parameter was actually omitted (versus being set to undefined):
f(undefined); // Second param omitted
function f(a, b) {
// Both a and b will evaluate to undefined when used in an expression
console.log(a); // undefined
console.log(b); // undefined
// But...
console.log("0" in arguments); // true
console.log("1" in arguments); // false
}
Footnotes
While undefined also isn't of type "number", it's whole job is to be a type that isn't really a type. That's why it's the value assumed by uninitialized variables, and the default return value for functions.
Just pass null as parameter value.
Added: you also can skip all consequent optional parameters after the last that you want to pass real value (in this case you may skip opt_timeoutInterval parameter at all)
By using ES6 javascript!
function myfunc(x = 1, y = 2, z = 6) {
console.log(x);
console.log(y);
console.log(z);
}
myfunc(5) //Output: 5 2 6
myfunc(3, undefined, 8) //Output: 3 2 8
// Better way!
function myfunc(x = 1, y = 2, z = 6) {
console.log(x);
console.log(y);
console.log(z);
}
// skip y argument using: ...[,] and it's mean to undefine
// 1 argument for ...[,] 2 arguments for ...[,,] and so on.....
myfunc(7, ...[, ], 4); //Output: 7 2 4
This question already has answers here:
Understanding JavaScript Truthy and Falsy
(9 answers)
Closed 12 months ago.
I wasn't really sure what to name this question, as that is almost the question itself.
Basically I was messing with some code and found something that I can't quite explain. Here's a simplification:
function foo (a, b) {
if (foo) {
console.log("foo is true");
} else if (!foo) {
console.log("foo is false");
}
}
foo();
This outputs "foo is true", but what I don't understand is how is Js evaluating a function without executing it ( lack of (); ) and how can I execute it even without passing parameters defined in the function.
Maybe I should say that the only language I really know is java.
It's simple:
Functions are just objects with an internal [[Call]] method.
All objects produce true when coerced to booleans.
In JavaScript, a function is a value (a somewhat special value, that you can call, using the () operator). In JavaScript, the following values are "false" when evaluated in a boolean context:
false
0
""
undefined
null
NaN
All other values are "true". Therefore, a function is always "true".
It is evaluating the reference to the function that the identifier foo is currently referring to. JavaScript uses object references to point to functions and variables, that you can change quite easily. This allows you to check which function you are currently referencing.
In Java your code would not be legal because the parameter signature has to match the function's parameter signature which includes the name of the function, and its parameter list.
In Javascript the only thing that matters is the name of the function. There is NO overloading in Javascript. This makes sense because Javascript's object model is based off of string -> function/property maps. Java's object model is more complex and nuanced which is why you can do overloading.
So in short. foo() will call your function foo, with a and b being undefined. If you call it with foo(5) a would be 5, and b would be undefined. If you called it with foo(5, 1, 3) a would be 5, b would be 1 and 3 would be ignored. I would guess that you can probably get at 3rd argument using the Javascript arguments variable. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Since a and b are undefined in your example, they evaluate to false. When you evaluate if(foo) you're passing the function object into the if() condition, and defined objects always evaluate to true. null and undefined both evaluate to false.
All falsey values in JavaScript
In javascript you're not required to pass any function arguments. When an argument is not passed the value of that argument is assumed to be undefined. It also prints "foo is true" because foo is defined as the function foo. You can see whats going on by running the following
function foo (a, b) {
console.log(typeof a);
console.log(typeof b);
console.log(typeof foo);
}
foo();
//it prints:
//undefined
//undefined
//function
Basically calling foo(); is like calling foo(undefined,undefined);
This question already has answers here:
What does "var FOO = FOO || {}" (assign a variable or an empty object to that variable) mean in Javascript?
(8 answers)
Closed 7 years ago.
I'm just getting going in javascript and am reading up on the module pattern.
I have been looking at this page: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html and cannot work out what the || {} statements mean.
There are quite a few places where this code is written: (UTIL || {}));
Can anyone explain what these statements mean and what they are doing?
I assume that || means OR - but am not too certain in this context.
Here is the code from the conclusion of the article. The second and the penultimate lines are examples of the code that has me puzzled.
var UTIL = (function (parent, $) {
var my = parent.ajax = parent.ajax || {};
my.get = function (url, params, callback) {
// ok, so I'm cheating a bit :)
return $.getJSON(url, params, callback);
};
// etc...
return parent;
}(UTIL || {}, jQuery));
This is used to define a variable if it is not set.
You can do this to ensure there is a value set!
for example:
function iHaveParameters(param1, param2) {
param1 = param1 || {} //empty object
param2 = param2 || "This should be a string"
}
And of course as noted, it will only invoke the second value when the first variable is null.
And in your case it is actually only setting the variable when it's not set, meaning if you include the script 3000 times, the variable will only still be defined once avoiding CPU. This way you could require the loading of a function for example
As has been said, it's an empty JavaScript object.
What's not so obvious I guess is why you would do that. A common reason is to make your code safe if the object happens to be null or undefined. Consider the example where you are passed an object and want to access an attribute of it:
function myFunc(obj) {
console.log(obj.name);
}
That's fine, unless obj is undefined, in which case your code will crash.
A safer way is often:
function myFunc(obj) {
console.log((obj || {}).name);
}
Now if obj is undefined then a new empty object is created instead. Getting the .name of that is safe and will simply return undefined.
This is obviously an over-simplified example, but the technique is widely used to make code shorter and easier to read (less tests and branches than putting if statements everywhere).
It means: if the object before || is null, use a new empty object {} instead.
Read more about the operator here: Is there a "null coalescing" operator in JavaScript?
{} is a short way of declaring an empty object, the same way as using [] do declare an empty array.
var my = parent.ajax = parent.ajax || {}; means that if the object parent.ajax exist then set it as the value. If not, set an empty object instead.
I've been working on a javascript library, and I have a lot of redundant checks like this:
if(typeof foo !== "undefined" && foo !== null)
So, I wanted to create a function that will be a shortcut to this unwieldy check. So I came up with this:
function isset(a)
{
return (typeof a !== "undefined" && a !== null) ? true : false;
}
But, since the value could be undefined, and it attempts to use a possibly undefined variable, it turns out to be useless.
Is there a way to accomplish this without have to extend a native prototype?
It really depends on what you mean by undefined.
1. You mean the variable does not exist.
In this case, what you want is not possible. typeof is an operator and therefore has magic behavior you just can't emulate using the language. If you try to pass a variable that doesn't exist to your function, it will throw a ReferenceError.
(See below for a workaround.)
2. You mean the variable has the value undefined, but does exist.
In this case, your function will do the trick -- though it could be simplified to the following:
function isset(variable) {
return variable != null;
}
This function will return false if the variable is either undefined or null. It takes advantage of the fact that undefined == null in JavaScript. Of course, with such a short function, one could argue that the function isn't needed at all.
Recall that a variable that is declared has a value -- undefined -- by default.
The name of your function suggests you mean case #1. I don't know what sort of library you are writing, but I can't imagine a case in a library where you would need to check if a variable exists, though I can definitely think of many possibilities for case #2.
If case #1 is necessary, remember that you can re-declare variables without changing their value:
a = 1; // pretend this was set somewhere higher up in the code
var a; // this does not change the value of `a`
If you re-declare variables before you use isset, you could avoid the ReferenceError problem. You won't be able to tell if the code has already declared the variable, though; you will only be able to tell if they have not assigned it to some other value.
You can check for null and undefined at the same time by using != instead.
// checks for both null and undefined
if( foo != null ) { ...
...so no need to use a function to shorten it.
null and undefined also evaluates to false in an if statement. So the following statement also works:
if(!foo)
...
This should cut it down significantly.
I do not understand why people keep promoting if (var) or if (!var). Both fail in my browsers. Meantime if (obj.prop) passes. This means that we should use if (this.someVar) or if (window.someVar) instead of if (varbl). Ok?