简体   繁体   中英

Javascript - defineProperty vs Prototype

I have just run into an unexpected problem whilst trying to create an array prototype for a function that emulates what is available in .net (linq) called SingleOrDefault().

Whilst the prototype function worked fine, I found that when iterating over a normal array using the following syntax for (var x in y) ... my function name appeared as one of the properties and broke my logic.

As a result of some googling I have redefined the function (below).

My question is, is the code in the Current block the right way to extend the Array object without causing any unwanted side effects?

Previous

Array.prototype.singleOrDefault = function (predicate) {
    var items = applyPredicate(this, predicate);
    if (items.length > 1) {
        throw new Error(errorOutput.multipleElements);
    }
    return (items) ? items[0] : null;
};

Current

Object.defineProperty(Array.prototype, 'singleOrDefault', {
    value: function (predicate) {
        var items = applyPredicate(this, predicate);
        if (items.length > 1) {
            throw new Error(errorOutput.multipleElements);
        }
        return (items) ? items[0] : null;
    },
    enumerable: false
});

Yes your 'current' code is correct, not as supported with older browsers as the previous code which is a downside if you need ie6/7 support (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty ).

You could use the object.hasOwnProperty method with the 'previous' code to achieve the same effect when you are iterating:

for (var x in y) {
     if (y.hasOwnProperty(y[x])) {
        //would filter out SingleOrDefault in your examples above
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM