1

Someone helped me with a great object prototype for JavaScript but it breaks in jQuery. In jQuery it gives an error:

jquery.min.js:2 Uncaught TypeError: V[g].exec is not a function

I found that the Object.defineProperty block (below) stops the jQuery error. But then it doesn't work. When I call to multiparter() it just returns "undefined". Can anyone help with a solution?

Object.prototype.multiparter = function(route) {
    var newObj = this;
    route.forEach(function(key) {
        newObj = newObj[key]
    });
    return newObj;
};

Object.defineProperty(Object.prototype, 'multiparter',{
    value : function() {},
    enumerable : false
});

var mekBldr = {
    mecha: {
        heads: {
            head01: {
                cost: 0,
                classification: ''
            }
        },
        rightLimbs: {
            legs: {
                rightleg01: {
                    cost: 0,
                    classification: ''
                }
            }
        },
        leftLimbs: {
            legs: {
                leftleg01: {
                    cost: 0,
                    classification: ''
                }
            }
        }
    }
};
var part = 'heads';
var stuck2 = [part];
var part1 = 'leftLimbs';
var part2 = 'legs';
var stuck = [part1, part2];
mekBldr.mecha.multiparter(stuck2).head01.cost = 2;
//goal: mekBldr.mecha.leftLimbs.legs.leftleg01.cost = 5;
mekBldr.mecha.multiparter(stuck).leftleg01.cost = 5;
Ultimater
  • 4,647
  • 2
  • 29
  • 43
Tachyon80
  • 147
  • 10

1 Answers1

1

By passing a value to the descriptor, you've just overwritten the method with that empty function (which is the one doing nothing and returning undefined). If you really want to define a method on Object.prototype (which you absolutely should not do), you'd need to use

Object.defineProperty(Object.prototype, 'multiparter', {
    value: function(route) {
        return route.reduce(function(newObj, key) {
            return newObj[key]
        }, this);
    },
    enumerable: false,
    configurable: true
});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks for the info. It sounds like I shouldn't solve my problem by using Object.prototype. What is a better solution? Towards the bottom of my code sample above, you can see "goal". That's what I'm trying to accomplish. Any help would be greatly appreciated. – Tachyon80 Oct 20 '16 at 17:17
  • Make it a static function: `multiparter(mekBldr.mecha, stuck2).head01.cost` not a method. One day you'd encounter an object that had its own `multiparter` property, and your code would break. – Bergi Oct 20 '16 at 17:20
  • Like this? `code`function multiparter(theObj,route) { route.forEach(function (key) { theObj = theObj[key] }); return theObj; }`code` – Tachyon80 Oct 20 '16 at 18:24
  • @user1592980 Yes, exactly. Though I recommend to use `reduce` instead of `forEach` like in my answer :-) – Bergi Oct 20 '16 at 18:43