0

This is my code -

function searchString(usrLogin) {

  var setUsrLogin = function (usrLogin) {
    this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
  }


  this.toString = function(){
    return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + this.usrLogin + '" ';
  }

  setUsrLogin(usrLogin);
}

$(function() {
  var a = new searchString("");
  $('#searchBar').val(a.toString());
});

a.toString() prints source="dbmon-dump://Source/ID" USR_LOGIN="undefined" because this.usrLogin shows up as undefined. What am I doing wrong?

5
  • You seem to be making the assumption that variables in functions and properties of this in the same functions are the same thing. Did you learn that somewhere? They're entirely separate. There are different solutions, but I'm not sure why you have these nested function in the first place. Commented Jul 10, 2013 at 13:41
  • I come from a Java background so that's a mistake on my part. Commented Jul 10, 2013 at 13:43
  • Ok, to use a solution most closely resembling your current code, you could change var setUsrLogin = func... to this.setUsrLogin = func..., then change the invocation to this.setUsrLogin(usrLogin). But overall there seems to be more functions here than needed. Commented Jul 10, 2013 at 13:44
  • Crazy Train is right You are using private varaibles of function as the method of instance object. this.usrLogin is an instance property where as userLogin is the variable Commented Jul 10, 2013 at 13:45
  • One more Thing in nested function Definitions inner function can not access the argument and this object of outer function so prob the issue too Commented Jul 10, 2013 at 13:48

5 Answers 5

6

When you call setUsrLogin(usrLogin);, your're losing the this context. In fact, the this on which you assign the usrLogin property on is the global object.

To fix this,

  • just remove that function call and set it directly:

    function searchString(usrLogin) {
        this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
        this.toString = function(){
            return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + this.usrLogin + '" ';
        }
    }
    
  • or pass the instance as parameter. Either

    function setUsrLogin(usrLogin) {
        this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
    }
    // and then
    setUsrLogin.call(this, usrLogin);
    

    or

    function setUsrLogin(search, usrLogin) {
        search.usrLogin = (usrLogin == "") ? "*" : usrLogin;
    }
    // and then
    setUsrLogin(this, usrLogin);
    

Btw, you might move the toString function to the prototype object:

function SearchString(usrLogin) {
   this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
}
SearchString.prototype.toString = function() {
    return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + this.usrLogin + '" ';
};
var a = new SearchString("");
Sign up to request clarification or add additional context in comments.

Comments

0
function searchString(usrLogin) {
    this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
    this.toString = function(){
    return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + this.usrLogin + '" ';
      };
}


  var a = new searchString("abc");
  alert(a.toString());

This will alert the string with a username, let me know if this helps or isn't what you are looking for. http://jsfiddle.net/rBe6x/

Comments

0

I agree with Bergi answer.

Here is another "simpler" solution:

    function searchString(usrLogin) {

      this.setUsrLogin = function (usrLogin) {
         this.usrLogin = (usrLogin == "") ? "*" : usrLogin;
      }

      this.toString = function(){
          return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + this.usrLogin + '" ';
      }

      this.setUsrLogin(usrLogin);
    }






Comments

0

The problem is that within your setUsrLogin function, this does not refer to the searchString instance.

What you can do is store a reference to your searchString function (which is definitely NOT a class) and use that to access the properties. Also, you could alter your setUsrLogin function to be like your toString function, which will then allow you to correctly access the searchString function using this.

This is one approach that will work:

function searchString(usrLogin) {
    var self = this;

    this.setUsrLogin = function (usrLogin) {
        self.usrLogin = (usrLogin == "") ? "*" : usrLogin;
    }

    this.toString = function () {
        return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + self.usrLogin + '" ';
    }

    self.setUsrLogin(usrLogin);
}

Here is a working example

19 Comments

@Bergi: No it does not, what?
stop using term class in javascipt. Use reference Type instead
"this refers to the toString function" It doesn't.
@chetanmehta: OP used term "class" that is why I used it, so they understood what I was referring to
@musefan: Hmmm... I tend to assume that people are waiting around to hear what I have to say. ;D
|
0

Bergi's answer pretty much covers it.

Adding another way of achieving it - using a variable to save the context of this

function searchString(usrLogin) {
  //save the context
  var that = this;
  var setUsrLogin = function (usrLogin) {
     //use that in the internal functions/methods
     that.usrLogin = (usrLogin == "") ? "*" : usrLogin;
  }


  this.toString = function(){
      //use that in the internal functions/methods [Not required in this case though]
      return 'source="dbmon-dump://Source/ID" ' + 'USR_LOGIN="' + that.usrLogin + '" ';
  }

  setUsrLogin(usrLogin);
}

4 Comments

You dont need to pass "that" into the toString() function. Just leave it as "this". Use "that", only for the setUsrLogin() function.
@ESt3b4n agreed, but if it is there it has no harm, it may avoid chances of human mistakes.
I am the one who try to avoid using variables to save the context of this, if there are other possible ways to achieve the problem, because it make generate a little confusion of why create/repeat the same thing in another variable... I would use it as a last resource.
@ESt3b4n I have added that in comment, that not required though, let the developer use that option as per the use case. Thanks for comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.