views:

60

answers:

5

Inside a function, I've got:

var myType;
if ( $(this).is(".whatever") ){
  myType = typeOne;
} else if ( $(this).is(".something") ){
  myType = typeTwo;
}

This works fine. However, I want to turn this into a separate function that I can call, since I use it in several different places. The function I write is:

function setMyType(){
  var myType;
  if ( $(this).is(".whatever") ){
    myType = typeOne;
  } else if ( $(this).is(".something") ){
    myType = typeTwo;
  }
}

When I call setMyType() in my main function, the main function can't access myType. If I alert(myType) inside setMyType(), the alert contains the correct value. But the main function can't see that value.

It's a scope issue, but I'm not sure how to resolve it. I tried defining myType inside the main function and passing it to setMyType(). While setMyType() gets the value of myType from the main function just fine, it still doesn't return the changed value to the main function.

A: 

Put myType in global scope (I added a "g" like global prefix):

// in global scope
var gMyType = null;

function setMyType(){
  if ( $(this).is(".whatever") ){
    gMyType = typeOne;
  } else if ( $(this).is(".something") ){
    gMyType = typeTwo;
  }
}

NB: I think you need to change the $(this) part

RC
+4  A: 

You would return the value from the function, like this:

function getMyType(){
  var myType;
  if ( $(this).is(".whatever") ){
    myType = typeOne;
  } else if ( $(this).is(".something") ){
    myType = typeTwo;
  }
  return myType;
}

// elsewhere:
var myType = getMyType();
Casey Hope
+1, although the method might better be named `getMyType` or similar
harto
Good point, edited.
Casey Hope
That did it. I thought I'd tried returning the value earlier, but I must have made a mistake somewhere.
motorfirebox
A: 

you can put it in global scope as @RC suggested or you can define it like this:

function setMyType(){
  if ( $(this).is(".whatever") ){
    document.window.gMyType = typeOne;
  } else if ( $(this).is(".something") ){
    document.window.gMyType = typeTwo;
  }
}

now you can access it from anywhere on page:

alert(document.window.myType);
TheVillageIdiot
A: 

Returning the value is probably the best solution, but here is another one. You can pass an object to the function that functions as scope and your value will be set as property of this object.

This is done often if you have a method to load external scripts to not pollute the global namespace:

function setMyType(scope){
  if ( $(this).is(".whatever") ){
    scope.myType = typeOne;
  } else if ( $(this).is(".something") ){
    scope.myType = typeTwo;
  }
}

which would be used like:

var scope = {};
setMyType(scope);
//now scope.myType contains your value

I don't encourage you to use this method in your situation (returning the value makes much more sense and is easier to understand) but it is worth mentioning it.

Felix Kling
A: 

Unless the function is being set inside a closure, or it is part of a jQuery call back that explicitly sets the this to the event handler element you will want to avoid relying on this inside the function since it will refer to itself.

function setMyType(obj){
  myType = ($(obj).is(".whatever"))?typeOne:(($obj).is(".something"))?typeTwo:null;
  return myType;
}

--a little ternary for good measure-- Mind you it would be just as easy in this case, if the object does contain this in a closure to simply set this.myType = setMyType(this) and if you return the value you will have it as an object property.

Gabriel
In the actual code, I have var that = $(this), and I use 'that' in the functions I call.
motorfirebox