Jump to content

Is my way of creating objects correct?


neonwarge04
 Share

Recommended Posts

Hi, 

I am new on javascript and I can't get my head wrapped on Objects. Is my way of creating objects correct? I am using this way along with require.js. I am having few comments from my colleague that this is somehow wrong.

 

define(
[  'pixi'
 , 'howler'
 , 'tween'
 , 'tweenmax'
 , 'src/Random.js'
 , 'src/Giant'
], 

function(PIXI, Howl, TWEEN, TweenLite, Random, Giant)
{
	var Direction = { Up : 0, Down : 1, Left : 2, Right : 3 };

	function Spawner(stage , direction)
	{
		var mDirection = direction;
		var mStage     = stage;

		var This = 
		{
			  get x(){ return mSprite.position.x; }
			, get y(){ return mSprite.position.y; }
			, set x(x){ mSprite.position.x = x; }
			, set y(y){ mSprite.position.y = y; }

			, function1 : function1
			, function2 : function2
			, function3 : function3
		};
		
		var mSprite = PIXI.Sprite.fromFrame('spawnarea.png');
		mSprite.anchor.x = 0.5;
		mSprite.anchor.y = 0.5;

		function function1(stage)
		{
		}

		function function2()
		{

		}
		
		function function3()
		{
		}

		return This;	
	}

	return {

		Direction : Direction

		, create : function(stage , direction)
		{
			return Spawner(stage , direction);
		}
	}
});

The reason I chose this method because I don't have to use the 'this' keyword every time I refer to my variables for functions. When I first started JS I did the the prototypal way and my code was a mess. Using this approach, I also don't have to bind to 'this' every time I reference outer variables from a callback function. I also have some variables/functions that are private and make them public by augmenting them to 'This = {}'. Basically the Spawner function is just simple a method for constructing the '{}' object. 

What do you think? Is there something that I missed here? Caveats? Cons on this approach? I'll appreciate your input very much.

 

Link to comment
Share on other sites

Your code uses closure to achieve data privacy and should work as intended. But it's a bit more complex than necessary, which may have thrown your colleague. Here's a simpler version of "create" that does the same thing:

create: function (stage, direction) {
            var mSprite = PIXI.Sprite.fromFrame('spawnarea.png');

            mSprite.anchor.x = 0.5;
            mSprite.anchor.y = 0.5;

            return {
                get x() { return mSprite.position.x; },
                get y() { return mSprite.position.y; },
                set x(x) { mSprite.position.x = x; },
                set y(y) { mSprite.position.y = y; },

                function1 : function () {},
                function2 : function () {}
            };
        }


This is fine if you're calling "create" for one or two dozen of these objects. However, if you're using "create" to construct thousands of these objects then this implementation is inefficient in both RAM and CPU cycles because you're reconstructing whole new copies of the inner functions each time create is invoked. If that's an issue for your situation then you can remedy it by moving those inner functions to a prototype object like so:

create: (function () {
            var baseClass = {
                get x() { return this._mSprite.position.x; },
                get y() { return this._mSprite.position.y; },
                set x(x) { this._mSprite.position.x = x; },
                set y(y) { this._mSprite.position.y = y; },

                function1 : function () {},
                function2 : function () {}
            };

            return function (stage, direction) {
                var mSprite = PIXI.Sprite.fromFrame('spawnarea.png');

                mSprite.anchor.x = 0.5;
                mSprite.anchor.y = 0.5;

                var myObj = Object.create(baseClass);

                myObj._mSprite = mSprite;
                myObj._stage = stage;
                myObj._direction = direction;

                return myObj;
            }
        })()

Note that now your private data is necessarily exposed as _mSprite, _stage, and _direction (the underscore is merely a convention used to denote properties that should be treated as private, but there is no actual privacy).

Link to comment
Share on other sites

Wow, thanks for this BobF. It finally came into my senses that what is prototype for. It means that those function are created each time but if they are a prototype of '{}' means all instance uses one copy those function. Since function is also treated as objects, it can be a problem in terms of RAM. The member variables of the object are then reference by 'this', which I highly avoided as it has convoluted my code from early attempts in javascript.

Thanks for the insight.

Link to comment
Share on other sites

define([], function()
{
	var MyClass = (function()
	{
		var x = "Hello World!";
			
		var MyClass = function(){};
		
		MyClass.prototype.sayHello = function()
		{
			console.log(x);
		}
		
		MyClass.prototype.setHelloMessage = function(mes)
		{
			x = mes;
		}
		
		return MyClass;
	})();
	
	return {
		create : function()
		{
			return MyClass();
		}
	}
});

I finally came up with this approach, going back to basic. I need to conserve memory because it is utmost importance in the project we are working on. I still need to work on the return though but we are working on it.

Thank you very much!

Link to comment
Share on other sites

Note that as the code is currently written, all objects instantiated by "create" will be sharing the same "x" value (i.e., a.sayHello() and b.sayHello() are guaranteed to always log the same message). Assuming that is not what you want, you will need to expose "x" as a property of MyClass.

Link to comment
Share on other sites

Hi BobF,

I noticed that as well. I finally settled down using the prototype approach when I deal with objects I planned to create multiple times and modular approach when I deal with classes I don't have to instantiate multiple times. At least, this what makes sense to me.

Thanks a lot for the input!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...