1

I am writing a little class and I don't get it why this doesn't work:

var Browsertest = {

    isIE: /MSIE (\d+\.\d+)/.test(this.getUserAgent()),

    getUserAgent: function() {
        return navigator.userAgent;
    }

};

console.log(Browsertest.isIE);

I get the error that getUserAgent() doesn't exists/is available (in IE9 and other browsers).

1
  • User agent detection should be used with caution, feature detection is way better :) Commented Mar 4, 2012 at 17:11

4 Answers 4

4

You're calling the getUserAgent function before it is defined. When using object literals, instance members need to be defined before they are used.

Two alternatives...

One:

var Browsertest = {
    getUserAgent: function() {
        return navigator.userAgent;
    },

    isIE: function() { return /MSIE (\d+\.\d+)/.test(this.getUserAgent()); }
};

console.log(Browsertest.isIE());

Two:

var Browsertest = new function() {
    var that = this;

    this.getUserAgent = function() {
        return navigator.userAgent;
    };

    this.isIE = /MSIE (\d+\.\d+)/.test(that.getUserAgent());
};

console.log(Browsertest.isIE);
Sign up to request clarification or add additional context in comments.

4 Comments

this still resolves to the global object there, no (first example)?
Your first solution would be the best, but it doesn't work even: I get the same error message: this.getUserAgent is not a function
Even if I replace this with Browser I get Browser is undefined
@poru - you guys are right - I just edited my answer. Michael originally had the right solution...
4

Since isIE is being defined as a property before getUserAgent(), you must define it as a function rather than a scalar:

var Browsertest = {

    isIE: function() {
      return /MSIE (\d+\.\d+)/.test(this.getUserAgent());
    },
    getUserAgent: function() {
        return navigator.userAgent;
    }
};
// Call it as a function
console.log(Browsertest.isIE());

Comments

1

You are calling this.getUserAgent in a place where this resolves to the global object.

4 Comments

this is not the first problem of his script but it's also a problem, good catch :)
Yeah, navigator.userAgent, uppercase variable name for a simple object, etc... I know :(
those were the first problems I noticed with it. Feature detection is widely favored over looking at the user agent string, and uppercase variable names for non-constructors are considered bad form. That and the code doesn't work, obviously
Oh ok I get it. Well, UA sniffing and naming conventions are not "problems" that make his code faulty as I was thinking in the first comment, but for sure they should be avoided :)
0

Well first i'd like to point out, please do not use user agent sniffing any more, it is highly frowned upon these days. See This link for more info why UA sniffing is bad

Answer to your question: It will work if you declare the getUserAgent method before the isIE method.

var Browsertest = {
    getUserAgent: function() {
        return navigator.userAgent;
    },

    isIE: /MSIE (\d+\.\d+)/.test(this.getUserAgent())
};

This is because:

/MSIE (\d+\.\d+)/.test(this.getUserAgent())

Is immediately executed when it is parsed, because it is an expression, not a function declaration. Therefore it does not know about getUserAgent, because that method has simply not yet been parsed.

But the method getUserAgent is redundant, so you could also write it like this:

var Browsertest = {
    isIE: /MSIE (\d+\.\d+)/.test(navigator.userAgent)
};

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.