Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript class inherit from Function class

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.

like image 422
dgreisen Avatar asked Nov 02 '11 23:11

dgreisen


People also ask

How do I inherit a class in JavaScript?

By calling the super() method in the constructor method, we call the parent's constructor method and gets access to the parent's properties and methods. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.

How JavaScript inherits from another class?

We use the extends keyword to say that this class inherits from another class. The Professor class adds a new property teaches , so we declare that. Since we want to set teaches when a new Professor is created, we define a constructor, which takes the name and teaches as arguments.

Can a function inherit a class?

Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.

What is prototypal inheritance in JavaScript?

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.


1 Answers

Your trying to inherit from Function. This is a right pain to do. I suggest you do the following instead

Live Example

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.

like image 159
Raynos Avatar answered Oct 03 '22 17:10

Raynos