Dmitry
Dmitry

Reputation: 1716

Prototype property for a function

I'm trying to get this:

a = new Foo(name); // a is function
a(); // returns a result
a.set(); // returns another result

I've implemented above like that:

function Foo (name) = {
  val = name;
  ret = function () { return val; }
  ret.set = function (v) { return val = v; }
  return ret;
}

Then, for multiple instances of Foo I'd like not to create method 'set', but share it through prototype property. However, all experiments I did have no effect. It works only on objects, not on functions. Even the code below doesn't work:

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

foo(); // a
foo.foo(); // foo
foo.bar(); // Uncaught TypeError: Object function () { return 'a'; } has no method 'bar' 

Upvotes: 4

Views: 91

Answers (3)

Tibos
Tibos

Reputation: 27843

Unfortunately there is no way to add a property to only some functions via the prototype chain. Functions have one object in their prototype chain, which is Function.prototype. There is no way to create functions which have other [[Prototype]]s.

The closest you can come to what you want are these two examples:

Your solution

function Foo (name) = {
  val = name;
  ret = function () { return val; }
  ret.set = function (v) { return val = v; }
  return ret;
}

Changing Function.prototype

Function.prototype.set = function (v) { return this.val = v; };
function Foo (name){
  ret = function () { return this.val; }
  ret.val = name;
  return ret;
}

var f = new Foo('myfunc');
f.set('myval');
console.log(f.val);

I would strongly recommend the first solution, because in the second one, every function shares the set property/method. Changing predefined Prototypes is usually frowned upon unless it's to port functionality from newer editions of the language.

Upvotes: 1

Ringo
Ringo

Reputation: 3967

Try this:

foo = function (name){
      this.name = name;
    }
foo.prototype.set = function(name){ return this.name = name; }

var f = new foo('yourName');
alert(f.name);
f.set('yourNameEdited');
alert(f.name);

Here's DEMO

Upvotes: 0

qwertynl
qwertynl

Reputation: 3933

In your last example foo does not have the function bar, only it's prototype does.

Therefore only a foo object would have the function bar


So you could do this:

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

var f = new foo(); // [object]
f.foo(); // TypeError: Object [object Object] has no method 'foo'
f.bar(); // bar

Upvotes: 0

Related Questions