0

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!

5
  • MF.prototype = {}; // set up any inheritance Don't do that. The function will already have a blank object on its prototype property, that line is at best a no-op. Commented Dec 3, 2013 at 9:31
  • @T.J.Crowder I agree, I have no idea why I left it there, thanks! Commented Dec 3, 2013 at 9:32
  • 1
    You need an instance of MF to use its forEach method. Try MF().foreach or attach the function to the constructor. Commented Dec 3, 2013 at 9:32
  • @elclanrs I see now, so I guess my best option would be to make it static. Commented Dec 3, 2013 at 9:36
  • Yes, if it needs to be public but it's not related to the instance. Commented Dec 3, 2013 at 9:37

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

About the side note, I'm not instancing this object ( or at least I think I'm not ). Basically how I use it is much like jQuery - MF('#selector'). I never use new MF(). Basically I don't really know what I'm doing but as long as it works I stick with it :D
@php_nub_qq: You're always using new MF. :-) Look at the first two lines of the function. Those ensure that if you do MF('#selector') it just turns around and does new MF('#selector'). If you don't need it to be a constructor function, I'd remove those lines and just new a local variable node rather than this.node.

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.