Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

object-creating function

The first couple paragraphs describe what I'm trying to achieve, the actual question is at the end. Thanks

Previously, I've simply been using new keyword to create objects, and prototypes to assign methods and handle inheritance. Recently, however, (partially inspired by CoffeeScript-generated JS) I decided to play with an object-creating function that would look something like this:

var Test = function(a) {
    function Test(a) {
        this.a = a;
    }
    var numCalls = 0;
    Test.prototype.output = function() {
        alert('I was initialized with ' + this.a);
        numCalls++;
    };
    Test.prototype.called = function() {
        alert('You called the output ' + numCalls + ' times');
    };
    return new Test(a);
};

I would then create a new object like this:

var obj = Test('string');

This approach has a couple of advantages over the typical approach that uses new for every instance. First, I'm much less likely to forget using the word new (I know there are other ways of avoiding new, but from what I've seen they have similar problems to the one I describe below), and second, I can easily see 'private' variables that constructor sees in any function that's now part of the class. I did run into a caveat when testing it though. instanceof no longer works because it doesn't see the inner-scoped object Test. To work around that, I tried to use constructor property instead:

var a = Test('one');
var b = Test('two');
a.constructor == b.constructor              // false
a.constructor.name == b.constructor.name    // true

And this is what got me confused. Creating the same objects without using an object-creating function would cause their constructor to be equal, but in this case they differ. My guess is that what's happening is that a brand new object type gets generated every time the function runs (the object structure is the same, but the instance of the prototype is different).

If my understanding of the problem is correct, does that also mean that the code is allocating additional memory per object instance to my JavaScript for functions that should be shared between instances by tricking it to create an identical object prototype for each instance (defeating the entire purpose of using prototype)? If so, is there a good way to avoid this while still keeping the benefits of this pattern (ability to share private variables between internal functions and not having to use new keyword)?

If I'm misunderstanding the problem, can someone enlighten me on what's actually happening?

like image 897
Alexander Tsepkov Avatar asked Feb 02 '13 22:02

Alexander Tsepkov


People also ask

Which function is used to create an object?

create() method creates a new object, using an existing object as the prototype of the newly created object.

What is the function of an object?

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax (a function parameter that can also be a function).


1 Answers

If so, is there a good way to avoid this while still keeping the benefits of this pattern...

Try using a module approach instead:

var Test = (function TestModule() {

  function Test(a) {
    this.a = a;
  }

  Test.prototype = {

  };

  return function(a) {
    return new Test(a);
  };

}());

var a = Test('foo');
var b = Test('baz');

a.constructor == b.constructor; // true
a.constructor.name == b.constructor.name; // true
like image 169
elclanrs Avatar answered Oct 07 '22 08:10

elclanrs