This question already has answers here:
Different ways to execute IIFE?
(2 answers)
Closed 8 years ago.
I've been using the following to begin filling out code for an IIFE:
(function() {
/* code goes here */
}());
On occasions I see the following being used:
(function() {
/* code goes here */
})();
Which is the correct one?
According to Douglas Crockford (the creator of jslint) the first one is less error prone when another developer reads your code. But not everyone has to respect this, both are fine though it is good to know what exists, and why.
When a function is to be invoked immediately, the entire invocation
expression should be wrapped in parens so that it is clear that the
value being produced is the result of the function and not the
function itself.
var collection = (function () {
var keys = [], values = [];
return {
get: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
return values[at];
}
},
set: function (key, value) {
var at = keys.indexOf(key);
if (at < 0) {
at = keys.length;
}
keys[at] = key;
values[at] = value;
},
remove: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
keys.splice(at, 1);
values.splice(at, 1);
}
}
}; }());
Its purely an aesthetic preference. Use whatcha like. Douglas Crockford tried real hard to popularize the first, but I more often see the second.
Related
This question already has answers here:
Can you alter a Javascript function after declaring it?
(12 answers)
Closed 6 years ago.
In our ordering system there is an embedded function I have no access to at all. Conveniently there is a spelling error in it so when a user clicks something a popup appears and has grammar issues in it.
Is there a way for me to replace that text or replace the function with a new function that has all the same code but correct spelling?
This is the function I need to edit.. note confirm says 'You selection' not 'Your selection'
I'd prefer to replace the whole thing because I may want to do some other edits but for now I'd like to fix that spelling error.
function showProof()
{
var blnSubmit = false;
var strHid='';
var strSave='';
if (aryTemplateChoices.length == 0)
{
blnSubmit = true;
}
else
{
for (var i=1; i<=aryTemplateChoices.length; i++)
{
strSave = aryTemplateChoices[i-1];
if (strSave=='')strSave='0';
if (document.getElementById('hidctrl'+ i))strHid = document.getElementById('hidctrl'+ i).value;
if (strHid=='')strHid='0';
if ((strSave != '0') && (strHid != strSave))
{
blnSubmit = true;
break;
}
}
}
if (blnSubmit)
{
if (confirm('Your selection has changed, do you want to save?'))
{
document.getElementById('subtype').value = 'proof';
document.getElementById('prevclick').value = '';
document.getElementById('frm1').submit();
}
}
canAddToCart();
//<!--WRITE-->
getQuantityPrice()
//<!--/WRITE-->
loadProof();
}
It doesn't really matter where the original function is and how you access it, as long as you just redefine the function (with the same name and corrected code) at a scope closer to where you want to use it.
Here's an example:
function foo(){
console.log("ORIGINAL foo says hello.");
}
function foo(){
console.log("NEW foo says hello.");
}
// The second declaration is in the same scope as the first, but it comes after the first
// so it overwrites that declaration and the second one is the one that is used.
foo();
I can create a recursive function in a variable like so:
/* Count down to 0 recursively.
*/
var functionHolder = function (counter) {
output(counter);
if (counter > 0) {
functionHolder(counter-1);
}
}
With this, functionHolder(3); would output 3 2 1 0. Let's say I did the following:
var copyFunction = functionHolder;
copyFunction(3); would output 3 2 1 0 as above. If I then changed functionHolder as follows:
functionHolder = function(whatever) {
output("Stop counting!");
Then functionHolder(3); would give Stop counting!, as expected.
copyFunction(3); now gives 3 Stop counting! as it refers to functionHolder, not the function (which it itself points to). This could be desirable in some circumstances, but is there a way to write the function so that it calls itself rather than the variable that holds it?
That is, is it possible to change only the line functionHolder(counter-1); so that going through all these steps still gives 3 2 1 0 when we call copyFunction(3);? I tried this(counter-1); but that gives me the error this is not a function.
Using Named Function Expressions:
You can give a function expression a name that is actually private and is only visible from inside of the function ifself:
var factorial = function myself (n) {
if (n <= 1) {
return 1;
}
return n * myself(n-1);
}
typeof myself === 'undefined'
Here myself is visible only inside of the function itself.
You can use this private name to call the function recursively.
See 13. Function Definition of the ECMAScript 5 spec:
The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.
Please note that Internet Explorer up to version 8 doesn't behave correctly as the name is actually visible in the enclosing variable environment, and it references a duplicate of the actual function (see patrick dw's comment below).
Using arguments.callee:
Alternatively you could use arguments.callee to refer to the current function:
var factorial = function (n) {
if (n <= 1) {
return 1;
}
return n * arguments.callee(n-1);
}
The 5th edition of ECMAScript forbids use of arguments.callee() in strict mode, however:
(From MDN): In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws when set or retrieved.
You can access the function itself using arguments.callee [MDN]:
if (counter>0) {
arguments.callee(counter-1);
}
This will break in strict mode, however.
You can use the Y-combinator: (Wikipedia)
// ES5 syntax
var Y = function Y(a) {
return (function (a) {
return a(a);
})(function (b) {
return a(function (a) {
return b(b)(a);
});
});
};
// ES6 syntax
const Y = a=>(a=>a(a))(b=>a(a=>b(b)(a)));
// If the function accepts more than one parameter:
const Y = a=>(a=>a(a))(b=>a((...a)=>b(b)(...a)));
And you can use it as this:
// ES5
var fn = Y(function(fn) {
return function(counter) {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
}
});
// ES6
const fn = Y(fn => counter => {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
});
I know this is an old question, but I thought I'd present one more solution that could be used if you'd like to avoid using named function expressions. (Not saying you should or should not avoid them, just presenting another solution)
var fn = (function() {
var innerFn = function(counter) {
console.log(counter);
if(counter > 0) {
innerFn(counter-1);
}
};
return innerFn;
})();
console.log("running fn");
fn(3);
var copyFn = fn;
console.log("running copyFn");
copyFn(3);
fn = function() { console.log("done"); };
console.log("fn after reassignment");
fn(3);
console.log("copyFn after reassignment of fn");
copyFn(3);
Here's one very simple example:
var counter = 0;
function getSlug(tokens) {
var slug = '';
if (!!tokens.length) {
slug = tokens.shift();
slug = slug.toLowerCase();
slug += getSlug(tokens);
counter += 1;
console.log('THE SLUG ELEMENT IS: %s, counter is: %s', slug, counter);
}
return slug;
}
var mySlug = getSlug(['This', 'Is', 'My', 'Slug']);
console.log('THE SLUG IS: %s', mySlug);
Notice that the counter counts "backwards" in regards to what slug's value is. This is because of the position at which we are logging these values, as the function recurs before logging -- so, we essentially keep nesting deeper and deeper into the call-stack before logging takes place.
Once the recursion meets the final call-stack item, it trampolines "out" of the function calls, whereas, the first increment of counter occurs inside of the last nested call.
I know this is not a "fix" on the Questioner's code, but given the title I thought I'd generically exemplify Recursion for a better understanding of recursion, outright.
Using filter and map, recursion example removing null properties from an object
const obj = {
name: {
first: "Jeson",
middle: null,
last: "Holder"
},
age: 45
}
function removeNullOrEmpty(obj){
return Object.fromEntries(
Object.entries(obj)
.filter(([_, v])=> v!== null && v.length !== 0)
.map(([k, v])=>[k, v === Object(v)?removeNullOrEmpty(v):v])
)
}
console.log(removeNullOrEmpty(obj))
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I'm creating an array of callbacks like this:
function createFunctions(n) {
var callbacks = [];
for (var i=0; i<n; i++) {
callbacks.push(function() {
return i;
});
}
return callbacks;
}
And, here's the test that I'm working with:
var callbacks = createFunctions(5);
for (var i=0; i<callbacks.length; i++) {
Test.assertEquals(callbacks[i](), i, 'Function with index ' + i);
}
Basically, I want the callback to return it's index in the array (i.e. callback[1]() should return 1). But, i defined in createFunctions is set to 6 when the test runs so they always return 6. I've tried creating a local variable to hold the value in the anonymous function but that's not working either.
Any ideas how to make this work?
A closure has an enduring reference to the variables it closes over, not a copy of their value as of when it was created. That's why all of your functions see 6: That's the value that i has as of when those functions are called.
If you need them to see different values, make the closures close over something else that doesn't change. Here's one way:
function createFunctions(n) {
var callbacks = [];
for (var i=0; i<n; i++) {
callbacks.push(makeCallback(i));
}
return callbacks;
function makeCallback(index) {
return function() {
return index;
};
}
}
Or:
function createFunctions(n) {
var callbacks = [];
for (var i=0; i<n; i++) {
callbacks.push(makeCallback(i));
}
return callbacks;
}
function makeCallback(index) {
return function() {
return index;
};
}
(In this example, it doesn't matter whether makeCallback is within createFunctions or outside it.)
Now, the callbacks close over the context containing the index argument. They each get their own copy of that context (which is created by calling the makeCallback function), and so since nothing ever changes index, its value remains unchanged.
More (on my blog): Closures are not complicated
This feature of closures closing over the context of the variable is very, very useful. Consider:
function allocator(start) {
return function() {
return ++start;
};
}
var f = allocator(0);
alert(f()); // "1"
alert(f()); // "2"
alert(f()); // "3"
That wouldn't work if the function created by allocator had a copy of the value of start. It works because the function created by allocator has a reference (through the context) to the variable itself.
this is a brief pattern of a javascript function which I am not able to understand.
this is as seen here:
https://github.com/g13n/ua.js/blob/master/src/ua.js.
Note: This an edited version as per HugoT's response to my original question's answer.
function D(arg) {
return function () {
return arg > 10; //arg is captured in this function's closure
}
};
object = {
x: D(11),
y: D(9),
z: D(12)
};
SO how does this structure work?
I can see the return is an object.
But I cant put the things together.
Is this a closure pattern?
Can anyone explain the flow?
Yes this is a closure pattern. Any arguments passed to D are captured in the closures of the function returned from D. However what you have written is not the same as in the code you linked.
This is the important part of the code you linked simplified
function D(arg) {
return function () {
return arg > 10; //arg is captured in this function's closure
}
};
object = {
x: D(11),
y: D(9),
z: D(12)
};
The values 11, 9 and 12 will be captured in the functions object.x, object.y and object.z.
Thus object.x() will return true while object.y will return false because 9 > 10 is false. object.z() will return true because 12 > 10
Let's break down ua.js to see what's going on. The outermost layer of the onion is an anonymous function:
var UA = (function (window, navigator)
{
/* anonymous function contents */
}(window, navigator));
So UA is set to the return value of this anonymous function. So what does the anonymous function do? It sets a variable ua.
var ua = (window.navigator && navigator.userAgent) || "";
It defines a function detect which returns an anonymous function which tests the contents of ua against pattern.
function detect(pattern) {
return function () {
return (pattern).test(ua);
};
}
Note that calling detect(/something/) does not return the value of (/something/).test(ua). It simply returns a closure that will perform the test on demand.
Now we hit the return value of our outer anonymous function, which looks like this (I've chopped out the comments):
return { isChrome: detect(/webkit\W.*(chrome|chromium)\W/i),
isFirefox: detect(/mozilla.*\Wfirefox\W/i),
isGecko: detect(/mozilla(?!.*webkit).*\Wgecko\W/i),
...
whoami: function () {
return ua;
} }
This is returning an instance of Object which contains a number of functions (isChrome etc), and those functions are the closures created by calls to detect(). This means that the execution of those (pattern).test(ua) checks are deferred until someone actually calls UA.isChrome() and so on.
You could imagine another approach where all the tests are performed up front, and UA becomes an Object containing a set of flags. This would have had the (probably fairly tiny) overhead of executing pattern matches that you as the developer are not interested in.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript infamous Loop problem?
I have the following code:
function test() {
var columns = options.columns;
for (var i =0; i < columns.length; i++) {
if (columns[i].type === "number") {
var field = columns[i].field;
columns[i].footerTemplate = function(data) { return buildFooter(data, field); };
}
}
}
function buildFooter(data, field) {
alert(field);
}
A library function calls the footerTemplate function (which in turn call buildFooter). The alert in buildFooter states that field is always the same value (the last value iterated in for loop of test.) How can buildFooter be called with the appropriate field value (i.e.
columns[0].footerTemplate = function(data) { return buildFooter(data, columns[0].field);}
and
columns[1].footerTemplate = function(data) { return buildFooter(data, columns[1].field);}
and so on...
Javascript does not scope variables inside logical blocks (loops, ifs). That field variable is shared across all the footerTemplate properties.
You can solve this by creating an inline function to create some scope:
for (var i =0; i < columns.length; i++) {
if (columns[i].type === "number") {
(function () {
var field = columns[i].field;
columns[i].footerTemplate = function(data) {
return buildFooter(data, field);
};
})();
}
}
}
Try:
columns[i].footerTemplate = (function(field) {
return function (data) {
buildFooter(data, field);
};
})(field);
It immediately executes a function that returns a new function that has the correctly bound field variable. It's definitely a scope issue that is a problem with loops, so using an immediately invoked function to create a new scope and making the correct variables available. This is definitely a duplicate of Javascript infamous Loop issue? though
Javascript is function-scoped language, so your decleration of
field
variable inside of for loop is the same as you declared it outside of foor loop, you're just overwriting same variable over and over again, there's no memory allocated for field variable in every loop, it's one same memory space that's being written to.