Zak Henry
Zak Henry

Reputation: 2185

arbitrary method names in javascript object

I'm learning more about javascript OOP by rolling my own console.log variant with some extra features I want.

So far I have

debug = {
        consoleAvailable :  (typeof console == "object"),
        reportToConsole : 0,
        list            : [],
        setReporting    : function(level){
                            this.reportToConsole = level;
                            return true;
                        },
        log             : function(){
                            if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function")  console.log.apply(console, this.log.arguments);
                            this.list.push({'type':'log', 'msg':this.log.arguments});
                            return true;
                        },
};

This is all working nicely, but I don't want to have to list all of the log,error,warning etc functions. Instead I would like to be able to just type debug.[something] and for a function to interpret that [something] and execute it in the same way as I have the log function working.

Is this even possible? If so how do I go about it?

Here is some examples of what I would like to be able to do.

debug.setReporting(1); //yes, I want to print to console

debug.log('foo', 'bar', 'baz'); //arbitrary number of arguments (this is already working)
debug.error('qux'); //function I haven't named, but there is a console.error function
debug.arbitraryName([1, 2, 3]); //no function for console.arbitraryName (ideally it would just console.log the argument(s)

Edit

Ok, it looks like @Rob W's method is the way to go, however I am having trouble implementing. It seems that I am not passing the name of the function correctly or similar. I have a fiddle here showing the problem http://jsfiddle.net/xiphiaz/mxF4m/

Conclusion

It looks like there is too many browser quirks to get a truly generic debugger without writing browser specific code, so instead I have just listed my most used log functions (log, warning and error). This does give me the option to further customize result of each of these functions.

result:

debug = {
    consoleAvailable :  (typeof console == "object"),
    reportToConsole : 0,
    list            : [],
    setReporting    : function(level){
                        this.reportToConsole = level;
                        return true;
                    },
    log             : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function")  console.log.apply(console, this.log.arguments);
                        this.list.push({type:'log', msg:this.log.arguments});
                        return true;
                    },
    warn            : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.warn=="function") console.warn.apply(console, this.warn.arguments);
                        this.list.push({type:'warn', msg:this.warn.arguments});
                        return true;
                    },
    error           : function(){
                        if (this.reportToConsole>0 && this.consoleAvailable && typeof console.error=="function")    console.error.apply(console, this.error.arguments);
                        this.list.push({type:'error', msg:this.error.arguments});
                        return true;
                    }
};

debug.setReporting(1);

debug.log('foo', 'bar', 'baz');
debug.error('qux');
debug.warn({test:"warning"});
console.log(debug.list);

Upvotes: 1

Views: 328

Answers (1)

Rob W
Rob W

Reputation: 349102

You can get an array of all properties (including non-enumerable ones) using the Object.getOwnProprtyNames method. Then, enumerate through it, and check whether the console[key] is a function. If yes, extend your own object with the method.

Object.getOwnPropertyNames(console)

As for your last quesion, there's a non-standard __noSuchMethod__ method which intercepts calls to undefined functions.

I strongly recommend to use my first proposed method, because the console method will not magically grow bigger. It also makes debugging easier.

Upvotes: 1

Related Questions