简体   繁体   中英

How to extend Object in JavaScript without losing the original functionality

I have a JavaScript object defined like so:

var Object = (function () {
    function Object() {
        this.id = RandomNumber();
    }

    // Custom Object.prototype / Object impementations here...

    return Object;
})();

The problem is that once this has been constructed, it loses original functionality like Object.defineProperty etc.

The idea is that I want to extend the basic functionality of Object, not re-write or overwrite the existing prototype.

How can this be achieved?

EDIT: Just to be clear, I know I can do this without affecting the original functionality:

Object.prototype.foo = function() { }

but I need to specifically add functionality to Object's constructor, ie

function Object() { this.id = 0; }

The new functionality must not overwrite the original Functionality.

Use the .prototype to add a property:

Object.prototype.specialMethod = function () {
    // Your method's code
};

And you'd use it like:

var a = {};
a.specialMethod();

Although I would discourage adding a property to the Object 's prototype, because it is enumerable and will mess up looping, and will be inherited by all objects, and objects that inherit from Object , which is basically everything.

You could actually use the Object.defineProperty method you mention:

Object.defineProperty(Object.prototype, "specialMethod", {
    enumerable: false,    // The important one, to avoid looping problems
    configurable: false,
    writable: false,
    value: function () {
        // Your method's code
    }
});

In order to extend this object you should create another object that has its prototype assigned a new instance of Object.

var Object = (function () {
    function Object() {
        this.id = 5;
    }

    Object.prototype.speak = function(prop){
       alert(this[prop]);
    }

    return Object;
})();

function ExtendsObject(prop){
    this.someProperty = prop;
}

ExtendsObject.prototype = new Object();

var xObj = new ExtendsObject("derived");
xObj.speak("id");
xObj.speak("someProperty");

Working Example: http://jsfiddle.net/RbCcA/

If you want to stick with the self executing functions here is the example rewrote:

var Object = (function () {
    function Object() {
        this.id = 5;
    }

    Object.prototype.speak = function(prop){
       alert(this[prop]);
    }

    return Object;
})();

var ExtendsObject = (function(){

    function ExtendsObject(prop){
       this.someProperty = prop;
    }

    ExtendsObject.prototype = new Object();

    return ExtendsObject;
})();

var xObj = new ExtendsObject("derived");
xObj.speak("id");
xObj.speak("someProperty");

Working Example: http://jsfiddle.net/RbCcA/1/

I do question the use of self executing functions in this situation. They are usually used to encapsulate and shield internals, however in the code example they are being exposed by returning the object from the SEF. Returning the object and storing it in a global variable just re-exposes the object, allowing its prototype and properties to be manipulated. Maybe there are private variables you have not mentioned, but as stated I find the SEFs unnecessary.

Do as Ian wrote. If you also want to check it the method already exists use

if (Object.prototype.specialMethod == null) Object.prototype.specialMethod = function() { ... };

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