Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New instance of function with object property

Tags:

javascript

Function are first class objects in JavaScript - but how to use that in combination with new?

I get how to make an object that acts both like a function and like an object

fetch.proxy = '127.0.0.1'
fetch(url)

But I am trying to figure out how I can combine this with creating a new intance so I can do something along the lines of:

a = new Fetch(host, username) 

a(path1) // fetches username@host/path1

a(path2) // fetches username@host/path2

(not so useful example with only 1 instance)

The following approach does not work as applying new returns an object (so get TypeError: object is not a function).

var Fetch = function(a, b){

    if ( (this instanceof arguments.callee) ){
        //called as constructor
        this.host = a
        this.username = b;
        this.host = 'localhost'

    } else {

   //called as function
   console.log("Fetching "+this.username+'@'+this.host+a);
    }
};

a = new Fetch('host', 'username') 

a('/path1') // TypeError: object is not a function

a('/path2') // TypeError: object is not a function

I have been playing with Fetch.prototype.constructor based on http://tobyho.com/2010/11/22/javascript-constructors-and/ and What it the significance of the Javascript constructor property? but must admit I have started to question if its possible at all.

Do you have any good ideas?

like image 632
mathiasrw Avatar asked Oct 25 '25 02:10

mathiasrw


1 Answers

how to use that in combination with new?

It doesn't make sense to do that. All that new Foo does is create a new object that inherits from Foo.prototype. However it is currently not possible to have some functions inherit from a prototype other than Function.prototype, so there is no advantage to use new Something to create a function.


Since you are not using prototype in your example, it doesn't matter though. Simply return a function from Fetch:

var Fetch = function(host, username){
  function fetch(path) {
     console.log("Fetching " + fetch.username + '@' + fetch.host + path);
  }
  fetch.username = username;
  fetch.host = host;
  return fetch;
};

Now you can call Fetch with or without new **, it doesn't make a difference:

var a = Fetch(host, username);
// same as
var a = new Fetch(host, username);

Note that I changed this.username to fetch.username in the above example. Every function has its own this value which does not refer to the function instance itself by default, so this.username would not work.

This would allow changing the host or username after the creation via a.username = 'something else';, etc. If you don't want that, simply change fetch.username to username.


**: If the function explicitly returns an object, then new will return that value instead of the newly created object inheriting from Fetch.prototype.

like image 89
Felix Kling Avatar answered Oct 27 '25 01:10

Felix Kling



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!