I like that in javascript, I can create a function, and then add further methods and attributes to that function
myInstance = function() {return 5}
myInstance.attr = 10
I would like to create a class to generate these objects. I assume I have to inherit from the Function base class.
In other words, I would like to:
var myInstance = new myFunctionClass()
var x = myInstance()
// x == 5
But I don't know how to create the myFunctionClass. I have tried the following, but it does not work:
var myFunctionClass = function() {Function.call(this, "return 5")}
myFunctionClass.prototype = new Function()
myInstance = new myFunctionClass()
myInstance()
// I would hope this would return 5, but instead I get
// TypeError: Property 'myInstance' of object #<Object> is not a function
I also tried the more complicated (and more proper?) inheritance method found here: How to "properly" create a custom object in JavaScript?, with no more luck. I have also tried using the util.inherits(myFunctionClass, Function) found in node.js. Still no luck
I have exhausted Google, and therefore feel that I must be missing something fundamental or obvious. Help would be greatly appreciated.
Your trying to inherit from Function
. This is a right pain to do. I suggest you do the following instead
var Proto = Object.create(Function.prototype);
Object.extend(Proto, {
constructor: function (d) {
console.log("construct, argument : ", d);
this.d = d;
// this is your constructor logic
},
call: function () {
console.log("call", this.d);
// this get's called when you invoke the "function" that is the instance
return "from call";
},
method: function () {
console.log("method");
// some method
return "return from method";
},
// some attr
attr: 42
});
You want to create a prototype object that forms the basis of your "class". It has your generic methods/attributes. It also has a constructor that gets invoked on object construction and a call method that gets invoked when you call the function
var functionFactory = function (proto) {
return function () {
var f = function () {
return f.call.apply(f, arguments);
};
Object.keys(proto).forEach(function (key) {
f[key] = proto[key];
});
f.constructor.apply(f, arguments);
return f;
}
}
A function factory takes a prototype object and returns a factory for it. The returned function when called will give you a new function object that "inherits" from your prototype object.
var protoFactory = functionFactory(proto);
var instance = protoFactory();
Here you create your factory and then create your instance.
However this isn't proper prototypical OO. we are just shallow copying properties of a prototype into a new object. So changes to the prototype will not reflect back to the original object.
If you want real prototypical OO then you need to use a hack.
var f = function () {
// your logic here
};
f.__proto__ = Proto;
Notice how we use the non-standard deprecated .__proto__
and we are mutating the value of [[Prototype]]
at run-time which is considered evil.