26

I'm writing a small JavaScript game framework and often use objects' properties, like

this.depth = this.y;

But these this'es are quite annoying @_@. Is there a way to write just…

depth = y;

…not affecting global object?

My instances are created via two factory functions, and they make a limited list of predefined variables, so all of them have depth, y, etc. Functions are applied to instances by .apply() method, though it all may be changed.

The reason I need to omit this keyword is that the framework is designed not for me only, but for other people too. I don't need to remove this in the framework itself, but the this keyword harvests much time while coding applications based on this library. The only solution I know so far is making 'private' variables, but it makes some inconvenience for people who haven't worked with JavaScript before, and manipulating obj1 from obj2 causes making lots of anonymous functions with .apply – even more hell. So, as I can see, there is no panacea in JavaScript.

Constructors:

/*...*/
'Copy' : function (type) {
  var obj = {
    'x':0,
    'y':0,
    'xprev':0,
    'yprev':0,
    /*...*/
  };
  return obj;
},
'make' : function (type,x,y) {
  obj = ct.types.Copy(type);
  obj.x = obj.xprev = obj.xstart = x;
  obj.y = obj.yprev = obj.ystart = y;

  /*...*/

  ct.stack.push(obj);
}
/*...*/
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    Seems like an XY problem. – elclanrs Feb 15 '15 at 11:03
  • no i think, you have to use this to refer current object – Ramesh Kotha Feb 15 '15 at 11:05
  • 1
    `this = t; t.depth=y`... but yeah, `this` is a part of the language. – serakfalcon Feb 15 '15 at 11:07
  • Please post your constructor function definition. – Dai Feb 15 '15 at 11:07
  • 2
    You can use with, but Everybody will shun you. – Jeremy Feb 15 '15 at 11:09
  • 9
    If you need `this` because you mean `this`, you need to write `this`. If you don't need `this` because you don't mean `this`, then you should omit `this`. There really isn't any one answer to your question. `this` does something very specific, and if that's what you want to do, then that's what you need to do. Sometimes you really do need to type 5 additional characters to get what you want. – deceze Feb 15 '15 at 11:22

2 Answers2

15

Your question is hard to answer without seeing any code, but in general, "modern" JavaScript OOP based on factories and closures is less verbose and more idiomatic than the old "wannabe Java" style with new's and this'es.

Old style:

function Something() {
   this.depth = 0;
}
Something.prototype.incDepth = function() {
   this.depth++;
}
foo = new Something()

New style:

function Something() {
   var depth = 0;
   return {
      incDepth: function() {
         depth++;
      }
   }
}
foo = Something()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
georg
  • 211,518
  • 52
  • 313
  • 390
  • 15
    With the caveat that the "new style" is less efficient since it creates many copies of `incDepth` for each instance. That's what `prototype` and `this` is for, to have a more efficient Java-like object with code inheritance without an actual class. – deceze Feb 15 '15 at 11:43
  • 5
    The "new style" also prevents you from extending prototypes (you can *try* to achieve the same thing by replacing the constructor function with a wrapper that adds a method to the result, but that's much more error-prone) or from determining what the type of an object is by checking its `.constructor` property, which is often useful when trying to get your head around poorly-documented libraries written in the "old style". – Mark Amery Feb 21 '15 at 12:47
0

I agree that the this keyword is not just annoying but also does not make much sense IMHO (at least the way it is implemented), as it encourages people to use global variables over properties.

IMHO it shouldn't be needed to access the properties of an object inside that object. (only if it needs to be distinguished from a parameter i.e.) On the other hand global variables could use a keyword, like globals.something

Sadly don't know a real solution, only to create a shortcut, like:

const t = this;
t.depth = t.y;

But I fear t will then be global too … :(

PS: So maybe better to have t as variable and at the beginning of each function write: t = this;

So you could have something similar to:

GameObject = {
  x: 5,
  y: 10,
  action: function() {
    t = this;
    t.depth = t.y;
    ...
  }
  ...
}
Stuepfnick
  • 71
  • 5