1
\$\begingroup\$

I don't want to extend the functionality of this method to include say library objects. I'm just looking for feedback on what it currently does.

ES5, section 8.6.2 "exposes" these global objects. I added a few Browser or "Host" objects which I needed for my purposes.

If needed I can add some more Browser or Host objects but no library objects as there is too much variety here. (i.e. jQuery, Backbone, etc.).

/*log
**  dependencies - none
**  browser - N/A
**
*/
$A.error = $A.report = $A.log = function (obj, note) {
    var logger,
        temp,
        type,
        ES5a = ['Arguments', 'Array', 'Object'],
        ES5b = ['Boolean', 'Date', 'Error', 'Function', 'JSON', 'Math',
            'Number', 'Null', 'RegExp', 'String', 'Undefined'],
        kindex,
        length;
    note = note || '';
    if (window.console) {
        logger = window.console.log.bind(window.console);
    } else {
        return;
    }
    type = Object.prototype.toString.call(obj).slice(8, -1);
    if (!type) {
        logger("Object type not found: ");
        logger(obj);
        return;
    }

    // Language Objects

    for (kindex in ES5a) {
        if (type === ES5a[kindex]) {
            try {
                temp = JSON.stringify(obj, null, 1);
            } catch (error) {
                temp = false;
            }
            if (temp) {
                logger("LOG|" + ES5a[kindex] + ">" + note + ">" + temp);
            } else {
                logger("LOG|" + ES5a[kindex] + ">" + note + ">");
                logger(obj);
            }
            return;
        }
    }
    for (kindex in ES5b) {
        if (type === ES5b[kindex]) {
            logger("LOG|" + ES5b[kindex] + ">" + note + ">" + obj);
            return;
        }
    }

    // Host Objects

    if (type === 'Event') {
        logger("LOG|B|Event>" + note + ">");
        if (obj.type) {
            logger("LOG|Event.type>> " + obj.type);
        }
        temp = obj.target || obj.srcElement;
        if (temp && temp.id) {
            logger("LOG|Event.target.id>> " + temp.id);
        }
        return;
    }
    if (type === 'HTMLDivElement') {
        logger("LOG|B|Div>" + note + ">");
        if (obj.id) {
            logger("LOG|Div.id>> " + obj.id);
        }
        return;
    }
    if (type === 'Storage') {
        for (kindex in obj) {
            if (obj.hasOwnProperty(kindex)) {
                logger("LOG|Storage>" + note + ">" + kindex + " | " + obj[kindex]);
            }
        }
        return;
    }
    if (type === 'HTMLCollection') {
        for (kindex = 0, length = obj.length; kindex < length; kindex++) {
            logger("LOG|HTMLCollection>" + note + ">" + kindex + " | " + obj[kindex]);
        }
        return;
    }

    // Library Objects

    if (win.jQuery && (obj instanceof win.jQuery)) {
        logger('LOG|jQuery object>');
        return;
    }

    // Not Found

    logger("LOG|B|NotFound>" + note + "> obj: " + obj + " | str: " + type);
};
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

JSON.stringify is a dangerous function. It fails, and thus your function too, on cyclic objects, on very deep or big objects, or simply on objects having some forbidden accessor deeply cached.

This object can't be logged by your function, for example :

var a = {}; a.b=a;

A related problem is that you only test the type of the external object. You don't detect the problem on this one :

var a = {parent:window};

What I would suggest is

  • either the addition of a try/catch (which may not be totally satisfying as some stringifications take time and memory before they fail),
  • to use or build another stringification function (see related SO question)
  • or simply to avoid the JSON format (of course it depends on your goal)
\$\endgroup\$
0

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.