How do I make this into a self-invoking function? - javascript

I'm not sure how to make this function into a self-invoking function. My code is looping through an array of zip codes from a JS file and sorting it from smallest to biggest and outputting it. I've found online that adding "())" at the end of the newZipCodeArray function, is supposed to self-invoke the function. However, it's not working. What am I doing wrong?
[enter image description here][1]
// Global variable
var zipCodeArray = [];
(function newZipCodeArray(currentZipCode) {
var valueFound = false;
for (zipCodeIndex = 0; zipCodeIndex <= zipCodeArray.length; zipCodeIndex++) {
if (currentZipCode === zipCodeArray[zipCodeIndex]) {
valueFound = true;
}
}
if (valueFound === false) {
zipCodeArray.push(currentZipCode);
}
}());
function newZipCodeArrayssignment12_3() {
// Instantiate variables.
var output;
var zipCodeRecords;
// Get the element.
output = document.getElementById('outputDiv');
zipCodeRecords = openZipCodeStudyRecordSet();
// Call the function to read the next record.
while (zipCodeRecords.readNextRecord()) {
currentZipCode = zipCodeRecords.getSampleZipCode();
newZipCodeArray(currentZipCode);
}
// Sort the zip code array.
zipCodeArray.sort();
}

The syntax involved in immediately-invoked (or self-invoked) functions doesn't allow it to be invoked from elsewhere. The IIFE pattern is intended to be used when the function only needs to be invoked once.
Note:
The grouping parenthesis wrapping the function change it from a declaration to an expression. And, as an expression, its name won't be added to the surrounding scope for other code to reference.
To invoke newZipCodeArray once right away and allow for it again later, you'll want to remove the parenthesis from around it and call it by name in a separate statement:
newZipCodeArray(); // first call
function newZipCodeArray(currentZipCode) {
// ...
}
function newZipCodeArrayssignment12_3() {
// ...
while (zipCodeRecords.readNextRecord()) {
// ...
newZipCodeArray(currentZipCode); // additional calls
}
// ...
}

Related

Accessing a JavaScript / jQuery Instance only once

I have a jQuery function which is called on several events (button click, change etc.)
This function is called in the documentReadyFunction and is feeded with start values..
everytime I call this function, parameters will be passed to the function.
My problem is: I don't want to create a new Object each time I call the function, because if I set a variable which decides if a part of the function is beeing executed or not, will be always overwritten..
What do I have to do, to access the first created instance instead of creating always a new one with every function call..
Down below is a simplyfied version of my function.. Maybe you understand my problem better then.
$.fn.doSomething = function(param1) {
var localParam = param1;
var amIcalledMoreThanOnce = parseInt(0, 10);
if (param1 == 1) {
amIcalledMoreThanOnce = amIcalledMoreThanOnce + 1;
if (amIcalledMoreThanOnce == 1) {
$('#run').val(amIcalledMoreThanOnce);
// fill form fields with URL parameters
// This shall be executed only once after getting the URL vals
} else {
// set the localParam to 0 to exit this loop and reach the outter else..
localParam = 0;
$.fn.doSomething(localParam);
}
} else {
$('#run').val(amIcalledMoreThanOnce);
// use the User Input Data not the URL Params
}
};
$.fn.doSomething(1);
$.fn.doSomething(1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<input type="number" id="run">
you can use this pattern:
var nameOfYourFunction = (function() {
var initializedOnlyOnce = {};
return function() {
//use initializedOnlyOnce here.
}
})();
here what you see is; you create and run a function immediately when the code is run. The outer function immediately returns the inner function and it's assigned to nameOfYourFunction. Then you can use the nameOfYourFunction(); just as any other function. However any varible declared in the outer function will be available to the nameOfYourFunction() and initializedOnlyOnce will never be initialized again.

how to get a property name which represent a function in JS

This is some JS code
var methodArr = ['firstFunc','secondFunc','thirdFunc'];
for(var i in methodArr)
{
window[methodName] = function()
{
console.log(methodName);
}
}
My problem is that how to get the name of a function in JS.
In JS, use this.callee.name.toString() can get the function name. But in this situation, it is a null value. How can i get the 'funName' string?
Sorry, I didn't make it clear.
I want to create functions in a for loop, all these functions has almost the same implementation which need its name. But others can call these functions use different name.I want to know what methodName function is called.
it seems a scope problem.
Try this:
var methodArr = ['firstFunc','secondFunc','thirdFunc'];
for(var i in methodArr) {
var methodName = methodArr[i]; // <---- this line missed in your code?
window[methodName] = (function(methodName) {
return function() {
console.log(methodName);
}
})(methodName);
}
window['secondFunc'](); // output: secondFunc

Javascript Initialization Closure

I'm trying to create javascript closure that will tell me if the function has already been run:
This is what I have so far:
function do()
{
var isInitialized = function()
{
var init = false;
if (init == false)
{
init = true;
return false;
}
return init;
}
if (!isInitialized())
{
// do stuff
}
}
My function isInitialized always evaluates to true. I'm like 90% sure I'm not setting the internal variable correctly. How do I fix my code?
First of all, you can't use do as your function name as that's a keyword.
Secondly, you can attach properties right to your function so you don't need a closure or anything like this:
function f() {
if(f.initialized)
return;
f.initialized = true;
console.log('Doing things.');
}
f();
f();
That will give you just one "Doing things." in the console.
Demo (run with your JavaScript console open): http://jsfiddle.net/ambiguous/QK27D/
Functions are objects in JavaScript so they can be assigned properties which provides a convenient mechanism for achieving what you want to do:
function doit() {
if (typeof doit.isInitialized === "undefined") {
doit.isInitialized = true;
// do stuff
}
}
Try this:
function fn(){
if (typeof fn.hasrun!='undefined'){return;}
fn.hasrun=true;
// do stuff
}
Every time you call isinitialized, it'll reset all the variables to default, so init will ALWAYS start out false. The values set afterwards are NOT carried over to the next time isInitialiazed is called.
What you want is a 'static' variable, which JS doesn't directly support, but can be simulated as per this answer: Static variables in JavaScript

Cannot call method 'split' of undefined - Called From Function

I have a JS function that is called on load that spilts some variables, this all works well, but when I call the function from another function, I get this error Cannot call method 'split' of undefined:
function loadInAttachmentsIntoSquads(){
// eg: 5000,5000,5000,5000 > [5000][5000][5000]
myAttachmentArray = currentAttachments.split(',');
//eg: [5000][5000][5000] > [5][0][0][0]
//myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');
setupWeaponAttachments();
}
function setupWeaponAttachments(){
myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');
//if(mySquadsIndex == 0){
if(myAttachmentForWeapon[1] == 1){ // if silencer is on? //first digit is always 5
weaponAttachments.silencer = true;
}
else{
weaponAttachments.silencer = false;
}
if(myAttachmentForWeapon[2] == 1){ // if silencer is on? //first digit is always 5
weaponAttachments.grip = true;
}
else{
weaponAttachments.grip = false;
}
if(myAttachmentForWeapon[3] == 1){ // if silencer is on? //first digit is always 5
weaponAttachments.redDot = true;
}
else{
weaponAttachments.redDot = false;
}
// -- applies visuals -- \\
applyWeaponAttachments();
}
If I call setupWeaponAttachments() from another function, I get that error ... why?
In the following:
> function loadInAttachmentsIntoSquads(){
>
> myAttachmentArray = currentAttachments.split(',');
>
> setupWeaponAttachments();
> }
The identifier currentAttachments is used as if it's a global variable. If it hasn't been assigned value, or its value isn't a string, at the time that the function is called, then an error will result.
So the fix is to make sure it has a string value:
function loadInAttachmentsIntoSquads(){
if (typeof currentAttachments != 'string') return;
...
}
or deal with the error some other way.
Also, where you are doing all those if..else blocks, consider:
weaponAttachments.silencer = myAttachmentForWeapon[1] == 1;
weaponAttachments.grip = myAttachmentForWeapon[2] == 1;
weaponAttachments.redDot = myAttachmentForWeapon[3] == 1;
It won't be any faster, but it is a lot less code to write and read.
You are misunderstanding/misusing the scope rules of JavaScript.
Try passing the array you're splitting explicitly and consistently, and it should solve your problem, as well as keeping the global namespace less cluttered:
First, pass the attachments in your first function explicitly:
function loadInAttachmentsIntoSquads(currentAttachments) {
var myAttachmentArray = currentAttachments.split(',');
setupWeaponAttachments(myAttachmentArray);
}
Note several things I'm doing above. First, I'm adding a currentAttachments argument to the function rather than just relying on a previously-declared global variable. Second, I'm declaring myAttachmentArray as a local variable by using the var keyword. Declaring variables with var declares them in local scope; failing to do so declares them in global scope. Third, I'm manually passing the array to the setupWeaponAttachments function, in which I will also receive the argument:
function setupWeaponAttachments(myAttachmentArray) {
var myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');
// [...]
}
Notice that I again properly declare the myAttachmentForWeapon variable in local scope.
If you are more careful with managing scope and properly define functions to receive the arguments they need and operate on them, you'll save yourself lots of headache in the future, and you'll get drastically fewer problems like these.

javascript function modification

I am trying to write a logger object which logs messages to screen. here is my code.
http://github.com/huseyinyilmaz/javascript-logger
in every function that needs to log something, I am writing loggerstart and loggerEnd functions at start and end of my functions. But I want to run thos codes automaticalls for every function. is there a way to modify Function prototype so every function call can run automatically.
(I am not using any javascript framework.)
EDIT: Rewritten the function to make it more modular
Well, this is a creepy way to do it, but I use this way sometimes when I need overriding some functions. It works well, allows any kind of customization and easy to understand (still creepy).
However, you will need to have all your functions stored in some kind of global object. See the example for details.
function dynamic_call_params(func, fp) {
return func(fp[0],fp[1],fp[2],fp[3],fp[4],fp[5],fp[6],fp[7],fp[8],fp[9],fp[10],fp[11],fp[12],fp[13],fp[14],fp[15],fp[16],fp[17],fp[18],fp[19]);
}
function attachWrapperToFunc(object, funcName, wrapperFunction) {
object["_original_function_"+funcName] = object[funcName];
object[funcName] = function() {
return wrapperFunction(object, object["_original_function_"+funcName], funcName, arguments);
}
}
function attachWrapperToObject(object, wrapperFunction) {
for (varname in object) {
if (typeof(object[varname]) == "function") {
attachWrapperToFunc(object, varname, wrapperFunction);
}
}
}
And some usage example:
var myProgram = new Object();
myProgram.function_one = function(a,b,c,d) {
alert(a+b+c+d);
}
myProgram.function_two = function(a,b) {
alert(a*b);
}
myProgram.function_three = function(a) {
alert(a);
}
function loggerWrapperFunction(functionObject, origFunction, origFunctionName, origParams) {
alert("start: "+origFunctionName);
var result = dynamic_call_params(origFunction, origParams);
alert("end: "+origFunctionName);
return result;
}
attachWrapperToObject(myProgram,loggerWrapperFunction);
myProgram.function_one(1,2,3,4);
myProgram.function_two(2,3);
myProgram.function_three(5);
Output will be:
start,10,end,start,6,end,start,5,end
So generally it allows you to wrap each function in some object automatically with a custom written wrapper function.
You could call every function with a wrapper function.
function wrapper(callback) {
loggerstart();
callback();
loggerend();
}
And call it with wrapper(yourfunction);

Categories

Resources