1

It is trivial to add prototypes to all Functions:

Function.prototype.foo = function () { return 'bar'; };
(new Function).foo();  // 'bar'

However, it is also bad practice to assign things to a global object's prototype, due to cross-module object reliance concerns, partially leading to the demise to earlier versions of prototype.js.

Suppose I want all of my functions to have the method foo. I would do something similar to this:

(function () {
    var Fn = Function;
    Fn.prototype.foo = function () { return 'bar'; };

    (new Fn).foo();  // 'bar'
}());

(new Function).foo()  // also 'bar'. this is bad!

Unfortunately, this affects Function's prototype as well, because Function was scoped by reference.

The usual "copy value" approach for passing primitive values into IIFEs would also fail, because Function itself is an object.

(function (Fn) {
    Fn.prototype.foo = function () { return 'bar'; };

    (new Fn).foo();  // 'bar'
}(Function));


Function.foo  // function () { return 'bar'; }

Given these examples, is it true that it is impossible to extend selected functions' prototypes, without affecting all other functions outside my scope?

Brian
  • 7,394
  • 3
  • 25
  • 46

2 Answers2

1

Create a prototype for your custom functions using new keyword.

That way, the original Function.prototype will not change:

(function (BaseFunction) {  
   var CustomFunction = function () { };
   CustomFunction.prototype = new BaseFunction();
   CustomFunction.prototype.foo = function () { return 'bar'; };
   console.log((new CustomFunction()).foo()); // 'bar'
})(Function);
console.log((new Function).foo); //undefined
Artyom Neustroev
  • 8,627
  • 5
  • 33
  • 57
0

As far as I know that's not possible. You could try something like this, to set more prototypes at once (fiddle: http://jsfiddle.net/ZgM8A/):

var ns = {};

(function(ns){
    var local = {};

    local.func1 = function() {
        this.p = "func1";
    }

    local.func2 = function() {
        this.p = "func2";
    }

    var proto = {
        name : "test"
    }

    for (var prop in local){
        if (local.hasOwnProperty(prop) && typeof local[prop] === "function"){
            local[prop].prototype = proto
        }
    }

    console.log(new local.func1());
    console.log(new local.func2());

}(ns))
pax162
  • 4,735
  • 2
  • 22
  • 28