Global variable in Javascript back to it's first value - javascript

I'm trying to make a function that get two parameters and do different stuff according to which step it's on.
So it's like a short quest with four steps.
var stp=1;
var vocabulary= new Array();
vocabulary['greatings']= ['привет','здорово','здравствуй'];
vocabulary['grQuestions']= ['как дела','что нового','как здоровье','как поживаешь'];
vocabulary['qrAnswers']= ['нормально как сам','спасибо хорошо','потихоньку','отлично'];
function myMission(stp,str) {
switch (stp) {
case 1:
{
if (jQuery.inArray(str, vocabulary['greatings'])!==-1) {
stp+=1;
$('.stp').html(stp);
$('.answer').html('Привет!');
} else {
$('.stp').html(stp);
$('.answer').html('Не понимаю');
}
}
break;
case 2:
alert("23");
break;
case 3:
alert("24");
break;
}
}
$(document).ready(function() {
$('#checker').click(function() {
var str = $('.yourVoice').val();
myMission(stp,str);
});
});
The problem is that stp always back to 1
how can I fix it?

The problem is that you are passing the value of stp to the function as a parameter. It then operates on its local copy and not the global variable.
To fix it, remove the stp parameter from the function definition and any calls to it.
function myMission(str) { ...
myMission(str);

Why do you complicate yourself using the same name for a global variable var stp=1; and a function argument function myMission(stp,str) ? The variable you're editing is the local one to the function scope, the global is not being affected at all.
If I understood well, you don't need the argument, and should only use the global variable.
function myMission(str) { ... }

When you do stp+=1 inside a function with a parameter with the same name, you are not working anymore with the global var, but you are working on the parameter that actually is a copy of the original var, so you are working on a totally different thing.
The solution can be to change the name of the parameter of the function:
function myMission(stp_another_name,str) {
...
Anyway if you want to work on the global var you can omit to pass it to function as parameter
function myMission(str) {
...
...
myMission(str);
Of course according the purpose of your code

Related

Explicitly scope a variable inside a function vs closure

I have the 'phone_dlg_manager' constructor function and its private methods show and init_country_code_combobox. The dialog reference is held in the phone_dlg variable. The show method triggers init_country_code_combobox and I have two options:
1) Explicitly pass the variable country_combobox that the init_country_code_combobox methods needs:
function phone_dlg_manager(ctx, open_dlg_button, edit_ctrl, item)
{
var phone_dlg;
show();
function show()
{
phone_dlg = ctx.application.ui.create_dialog(0, "PhoneEditorDlg");
init_country_code_combobox(phone_dlg.country);
read_to_dialog_controls(this._form_item);
phone_dlg.visible = true;
}
function init_country_code_combobox(country_combobox)
{
country_combobox.items.clear();
country_combobox.items.start_adding();
country_combobox.items.finish_adding();
}
}
2) Since phone_dlg is accessible withing init_country_code_combobox through closure, I can access the property that I need without explicitly passing the variable:
function phone_dlg_manager(ctx, open_dlg_button, edit_ctrl, item)
{
var phone_dlg;
show();
function show()
{
phone_dlg = ctx.application.ui.create_dialog(0, "PhoneEditorDlg");
init_country_code_combobox(phone_dlg.country);
read_to_dialog_controls(this._form_item);
phone_dlg.visible = true;
}
function init_country_code_combobox()
{
var country_combobox = phone_dlg.country;
country_combobox.items.clear();
country_combobox.items.start_adding();
country_combobox.items.finish_adding();
}
}
The second option seems easier to understand when reading code, however it makes the init_country_code_combobox function know more than it needs. Which option should I choose?
Thanks
This is mostly a matter of style. Option 1 is a little cleaner, and more extensible, since you can use init_country_code_combobox() to initialize more than just the one dialog. But if this is unlikely to be necessary, option 2 is not unreasonable.

passing an object to a function in javascript

This might seem like a noob question but I'm not sure what to do. I have function with 2 variables.
function someInfo(myVar1,myVar2)
{
this.lmyVar1=myVar1;
this.myVar2=myVar2;
}
myInstance=new someInfo("string1","string2");
function drawVariables(){
document.write(myInstance.myVar1);
document.write(myInstance.myVar2);
}
I want to use the same drawVariable() for multiple instances. I just can't figure out how the exact syntax for that. How can I make drawVariable() use a different instance of someInfo without repeating anything? Is there a simple example or tutorial I can follow?
Add an argument to the definition of function drawVariables. In the code below, this argument is called info. Now you can use info as your object inside the drawVariables function, and while calling drawVariables function, you can pass whatever instance you want to pass it. drawVariables function would now work with whatever instance you pass it while calling.
function someInfo(myVar1,myVar2)
{
this.myVar1=myVar1;
this.myVar2=myVar2;
}
// Create two separate instances
myInstance=new someInfo("string1", "string1");
myInstance2 = new someInfo("string2", "string2");
// info is the argument that represents the instance passed to this function
function drawVariables(info){
alert(info.myVar1 + ", " + info.myVar2);
}
// Call the function twice with different instances
drawVariables(myInstance);
drawVariables(myInstance2);
See http://jsfiddle.net/WLHuL/ for a demo.
function drawVariables(instance){
document.write(instance.myVar1);
document.write(instance.myVar2);
}
Would it make sense for you to do it this way?
function someInfo(myVar1, myVar2)
{
this.lmyVar1 = myVar1;
this.myVar2 = myVar2;
this.drawVariables = function ()
{
document.write(this.lmyVar1);
document.write(this.myVar2);
}
}
function Test()
{
var obj1 = new someInfo("aaa", "bbb");
var obj2 = new someInfo("xxx", "zzz");
obj1.drawVariables();
obj2.drawVariables();
}

JavaScript global variables declaration

The following script works correctly although I need to make few amends. In each function I am getting the values need for the different formulas. However I tend to replicate the same line of code in different functions.
Ex.
function one(){ var v1= document.getElementById('one').value; }
function two(){ var v1= document.getElementById('one').value; }
Full code
I would like to declare all of the variables once and than only use the ones I need for the specific functions. If I declare them right at the top than once they are called they still hold the original value so I need to update that value to the current one if changed of course.
Your code will be very hard to read if you do it like in your fiddle.
Instead do
var myVars;
window.onload=function() {
myVars = {
'list_price': document.getElementById('list_price'),
'negotiated': document.getElementById('negotiated'),
.
.
'lease_payment': document.getElementById('lease_payment')
}
now you can do
var price = myVars.list_price.value;
or perhaps add a function
function getVal(id) {
var val = document.getElementById(id).value;
if (val =="" || isNaN(val)) return 0;
return parsetInt(val,10);
}
now you can do
var price = getVal("list_price");
mplungjan's solution is a great one. If you're at all concerned by your global vars leaking into the window scope, wrap your code in an Immediately Invoked Function Expression to prevent that from happening:
(function(){
// code goes here
}());
There are two ways to go about this:
Update your variable when the value changes
Use a function that always returns the correct value
1) You can add a listener for the change event or the keyup event that changes your global variable:
// save initial value
var val = document.getElementById('one').value;
// update the value when input is changed
addEventListener(document.getElementById('one'), 'change', function() {
val = document.getElementById('one').value;
});
console.log(val);
2) You can use a function that always returns the current value:
var val = function() { return document.getElementById('one').value; };
console.log(val());
2b) If you hate parenthesis, you can define a property that uses the function above as a getter:
Object.defineProperty(window, 'one', {
get : function() { return document.getElementById('one').value; }
});
console.log(one);

javascript: dynamic call of nested function

in an existing implementation (can't change the structure much), i'm trying to call a function which is nested inside another function:
function outer(innerFunction, obj) {
//TODO: call innerFunction here, passing obj as first parameter
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
jsfiddle is here: http://jsfiddle.net/tbyyw/
i've alreay thought about using eval(), but i don't know how to pass an object - and they say 'eval is evil' ;)
another solution i've come up with is checking the innerFunction string, but this means i have to know which inner functions exist (besides, adding new functions would mean having to write extra checks then):
if(innerFunction == 'inner1') inner1(obj);
so is there another way without changing the overall implementation?
Without changing the overall structure eval appears to be the only option:
function outer(funcName, obj) {
var func = eval(funcName);
func(obj);
function inner1(obj) {
alert(obj.key);
}
}
There's nothing particularly "evil" about eval as long as you have full control over the code, but if you want, you can insert an additional security check:
if (funcName.match(/\W/))
throw "invalid function name!";
var func = eval(funcName);
This will raise an exception if someone tries to pass anything else than a simple identifier, i.e. a function name.
Is this what you wanted?
function outer(innerFunction, obj) {
var fn = {
inner1: function (obj) {
alert(obj.key);
}
};
fn[innerFunction](obj);
}
outer('inner1', {key:'value'});
http://jsfiddle.net/tbyyw/1/
A simple switch statement would be least intrusive. Or is the function name completely dynamic?
function outer(innerFunction, obj) {
switch (innerFunction) {
case "inner1": inner1(obj); break;
}
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
​

How to change the order of which they are called?

I have a quite inconvenient problem.
Say that I have the following functions
function name(namearg){
...
..
}
function handlefailed(){
..
..
}
function handlecover(){
..
..
}
Now to my problem, I have alot of hard coded html that can't be changed that is calling both functions like this
Link
Link
Link
The problem is the order of which I'm calling the functions, I first want to see which function that is called, either handlefailed() or handlecover(), and then want to know what name that is sent to the name function.
If I would have called the functions in the other way around I would just have done
var theName;
function name(namearg){
theName = namearg
}
function handlefailed(){
callOtherfunctionInAnotherJavascript(getElements(theName + ".failed"));
}
function handlecover(){
callOtherfunctionInAnotherJavascript(getElements(theName + ".cover"));
}
But now this is not possible since I'm calling the name function after the first function.
Is there a way in javascript that "changes" the order of how the functions are evaluated, or do you guys have a clever sollution to my problem, I.E getting the value of the namearg variable and use it in the handlefailed() & handlecover() functions?
var postFix;
function name(namearg){
callOtherfunctionInAnotherJavascript(getElements(namearg + postFix));
}
function handlefailed(){ postFix = '.failed'; }
function handlecover(){ postFix = '.cover'; }
you can empty both functions:
function handlefailed(){
..
..
}
function handlecover(){
..
..
}
and create two new functions that doing what you need
function handlefailed2(){
..
..
}
function handlecover2(){
..
..
}
then call the new functions from inside function name(namearg) according namearg deside to which function you want to call
You can declare another global, handleFunc, and have handlefailed/handlecover assign which one to call in name.
var theName;
var handleFunc = null;
function name(namearg)
{
if(handleFunc instanceof Function)
{
handleFunc(namearg);
handleFunc = null;
}
theName = namearg
}
function handlefailedCallback(namearg){ /* some code */}
function handlefailed()
{
handleFunc = handlefailedCallback;
}
function handlecoverCallback(namearg){ /* some code */}
function handlecover()
{
handleFunc = handlecoverCallback;
}
This gives you the flexibility to continue using name without breaking other areas of the code.

Categories