php_nub_qq
php_nub_qq

Reputation: 16015

Javascript module pattern issue

I have this module

var MF = (function() { // module pattern start
    function MF(selector) {
        if (!(this instanceof MF))
            return new MF(selector); // always construct
        this.node = null; // expose your DO
        if (typeof selector === 'string') {
            switch (selector.substring(0, 1)) {
                case '#':
                    this.node = document.getElementById(selector.substring(1));
                    break;
                case '.':
                    this.node = document.getElementsByClassName(selector.substring(1).replace('.', ' '));
                    break;
                default :
                    this.node = document.getElementsByTagName(selector);
                    break;
            }
            if (this.node.length > 1) {
                return MFList(this.node);
            } else if (typeof this.node.length !== 'undefined') {
                return MF(this.node[0]);
            }
        } else if (selector instanceof HTMLElement) {
            this.node = selector;
        }
    }
    function isArraylike(obj) {
        var length = obj.length;
        return (length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj);
    }
    function MFList(List) {
        var _List = [];
        MF.foreach(List, function(k, v) {
            _List[k] = new MF(v);
        });
        return _List.length > 0 ? _List : false;
    };

    MF.prototype.foreach = function(obj, callback) {
        var value,
                i = 0,
                isArray = isArraylike(obj);

        if (isArray) {
            var length = obj.length;
            for (; i < length; i++) {
                value = callback.call(obj[ i ], i, obj[ i ]);

                if (value === false) {
                    break;
                }
            }
        } else {
            for (i in obj) {
                value = callback.call(obj[ i ], i, obj[ i ]);

                if (value === false) {
                    break;
                }
            }
        }

        return obj;
    }
    return MF; // pass refence out
}()); // module pattern end

I have to admit, javascript's object model is quite confusing for me. The error I'm getting is that it doesn't recognize MF.foreach in function MFList. I'm not quite aware of how instances work with this module pattern but I'd be really glad if someone could tell me how I can call MF.foreach inside a private function of the object? Thanks!

Upvotes: 0

Views: 73

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074238

The error I'm getting is that it doesn't recognize MF.foreach in function MFList.

Right. The function MF doesn't have a property called foreach. Objects created via the function MF have a property called foreach (they get it from the prototype they're assigned via the new operator when you do new MF(...)).

If you wanted MF itself to have that function instead of objects created by it having that function, you'd change

MF.prototype.foreach = ...

to

MF.foreach = ....

MF.prototype is used to set the prototype of objects created via new MF; the properties you put there have no other connection to the MF function.


Side note: I would strongly recommend refactoring the MF function. You're using it as a constructor function, but sometimes it returns objects using the object MF.prototype as their prototype, other times it returns arrays. That kind of inconsistency is a bad idea. When a function is designed to be called via new (e.g., it's a constructor function), the normal case is that it doesn't return anything; the result of the new FunctionName expression will be the object created via new. But if the constructor function returns a non-null object (such as when you're returning an array), that overrides the normal result of the new expression.

Upvotes: 3

Related Questions