5

So I created a function like this,

var functionName = function(arg1) { //code logic here; }

At the same time, I need this function to work as an object. It will not really save anything, but the data will be accessed from another object.

var myObj = new Object();
myObj.x = 3;
myObj.y = 4;

So when I go, functionName.x it should return myObj.x. The myObj object is being maintained someplace else and I don't have any control of it.

This is how I currently implemented it,

functionName.__proto__ = myObj;

It works fine. But __proto__ is deprecated already and I would want to see if there is any other safe way of doing it. I thought of overriding Function.prototype but it doesn't work.

rene
  • 41,474
  • 78
  • 114
  • 152
John Ng
  • 869
  • 3
  • 15
  • 28
  • Why don't you just store in **functionName** just a reference to **myObj** ? – ngonzalvez Sep 16 '12 at 01:37
  • @Kryz I'm not sure I understand. I can't do functionName = myObj cuz that will override the function definition. Currently, functionName is being accessed as functionName() and functionName.x so I need to maintain the behavior. – John Ng Sep 16 '12 at 01:45
  • A side remark: myObj should probably be derived from Function.prototype, so that you still have access to functionName.bind, etc. (Of course, this has nothing to do with the original problem.) – Marc Jun 06 '13 at 11:03

3 Answers3

1

You want to implement a delegate to myObj:

     var functionName = function(arg1) { // code }

     functionName.myObj = new MyObj();
     for (prop in functionName.myObj) {
       if (functionName.myObj.hasOwnProperty(prop)) {
         functionName.__defineGetter__(prop, function() { return functionName.myObj[prop]; } );
       }
     }
Tanzeeb Khalili
  • 7,324
  • 2
  • 23
  • 27
  • what I see here is everytime functionName() is called as a function, it will go through each item in myObj. Which could be slow. That object could contain upto 500 elements. And, if functionName() is never called, then the getters won't be defined. For example, some pages would just use functionName.x directly without using functionName() – John Ng Sep 16 '12 at 02:36
  • I assumed functionName was a constructor. Updating the answer to work for a normal function. – Tanzeeb Khalili Sep 16 '12 at 03:11
  • I think were missing a point here. myObj is already defined somewhere and keeps a collection of objects that is dynamic. Meaning, it might lose or gain more elements at run time. I cant just copy the contents to functionName because once myObj gets updated, then it wouldnt be in sync with functionName. I need functionName, or its prototype, to hold a refernce to myObj. This works when I do functionName.__proto__ = myObj but I need to find an alternative to __proto__ use, – John Ng Sep 16 '12 at 04:28
1

I am having the same problem here. Unfortunately, there is no good solution under EcmaScript 5.1.

In the language specification http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf it says in 13.2 "Creating Function Objects" that the [[Prototype]] internal property of a newly created function object is always the standard built-in Function prototype object.

As detailed in 13.3 of the same specification, using the Function constructor is also of no help as a function constructed by new Function(…) also uses the method detailed in 13.2. (This is reflected by the fact that the prototype property of Function is neither writable nor configurable.

So to achieve what you want, you need a method to change the prototype of already existing objects. Fortunately, the upcoming Ecmascript 6 standard seems to standardises Object.prototype.__proto__ as per annex B.2.2 in the recent draft http://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:working_draft_ecma-262_edition_6_05-14-13-nomarkup.pdf.

Marc
  • 4,327
  • 4
  • 30
  • 46
-1

You could set the prototype of the function.

function functionName(arg1) { 
    //code logic here;
}

var myObj = { x: 3, y: 4 };
functionName.prototype = myObj;

var obj = new functionName();
console.log(obj.x, obj.y); // will output 3, 4
xdazz
  • 158,678
  • 38
  • 247
  • 274
  • I need to access these from functionName directly. The use of functionName() and functionName.x is all over different pages and it won't be practical enough to change each one. – John Ng Sep 16 '12 at 02:41
  • 1
    This doesn't answer the OP's question at all. The OP wants to create a function with a custom `__proto__`. This doesn't do that. Hence it should be deleted. – Aadit M Shah Nov 01 '14 at 15:29