this ? ughh, what?

Ultimatony

Veteran
Veteran
Joined
Jan 6, 2016
Messages
72
Reaction score
6
I'm learning JS and doing well, but I can't read the rpg_objects.js code because of all the "this", I just don't get it.


In the rpg_objects.js there are 1570 functions, but "this" is said 3703 times. So until I understand "this" I can't read the code.


I've read a couple articles and the concept still evades me, could anyone explain it well or link me to something that does?
 

taarna23

Marshmallow Princess
Global Mod
Joined
Jul 20, 2012
Messages
2,402
Reaction score
4,969
First Language
English
Primarily Uses
RMMZ
In many programming languages, the keyword this denotes the current object. So if you have an instance of (and I'm just pulling this out of the air, not from the RM code in any way at all) a character sprite, and you say something like this.height = 40, it will set that instance of a character sprite's height to 40.


I'm almost certain somebody that's had coffee could explain it more clearly.
 

Zalerinian

Jack of all Errors
Veteran
Joined
Dec 17, 2012
Messages
4,696
Reaction score
935
First Language
English
Primarily Uses
N/A
RPG Maker MV is designed to use objects, which is to say that the classes you see defined in the script files are used as a template to make a more complex variable, essentially. There are many different types of variables, but the main two we care about in this case are local carcasses and instance variables.


Local variables are anything you define in a function by saying "var variableName". Once the function is done running, these variables disappear and are no longer usable. Instance variables, however, stay around as long as an object exists. They're variables inside a class that can be used in any of that class's functions, and they will be usable as long as the object exists. Each object has separate instance variables whose value is completely independent of any other object. They can all be different. 


Local variables and instance variables can have the same name, because the computer remembers them differently. So how do we make sure the computer knows which version to use? "this.variableName" tells it to use the instance variable. "this" refers to the object currently running code, and it will use it's instance variables. 
 

Andar

Veteran
Veteran
Joined
Mar 5, 2013
Messages
31,430
Reaction score
7,711
First Language
German
Primarily Uses
RMMV
To give you some additional info:


"This" is a concept that is vital to a type of programming that is called object-oriented programming as opposed to the older way of functional programming (which still is what most people start with).


In functional programming, you basically wander through a long line of commands - there are branches and jumps, but the core logic mostly goes along the code lines.


Which also means that everything is directly connected and can access every other part, which caused some problems in large projects.


In object oriented programming, you partition the entire code depending on which part of the complex task you're handling, and limit each function to its objects, and create those objects when needed (instead of declaring everything in advance like for example Pascal does).


However, because you do not know when which object is created, you need a placeholder to tell the program that the current active object should handle the method - even if you don't exactly know which instance or variant of the objects in your program that is before the code is run. "this" is one of those placeholders that is in runtime replaced with the current active object.
 

sagebrushfire

Villager
Member
Joined
Jun 12, 2016
Messages
25
Reaction score
12
First Language
English
Primarily Uses
First of all, Mister.Right just made a nice little post about this: 





Second of all, I made a lengthy response in someone else's thread and I think it might help you. I have changed it a bit for you: 


Introduction to "this" in JavaScript


Given no context at all, this will be the same as the window object (the mother of all objects, parent of everything).


console.log(this); // In most browser consoles this will display the window object & all its details.




When used inside of a function, this will refer to the object that houses that function, like so: 


var MyNewObject = {};

MyNewObject.name = "Sam";

MyNewObject.greetings= function(){
console.log("My Name is" + this.name);
};

MyNewObject.greetings(); // prints "My Name is Sam" in the console. 




When used in a constructor function with the new keyword, this will refer to the new object that is being created: 


var CoolObject = function(nameInput){

this.name = nameInput;

this.greeting = function(){
console.log("My name is " + this.name);
};
};

var MyNewObject = new CoolObject("Sally");

MyNewObject.greeting(); // Logs "My name is Sally"


Because that is a constructor function, those properties do not just inherently exist inside of it. You can't do CoolObject.name, it won't work. The name property is using the this keyword and will only exist when the function is run with the new keyword so that it creates a new object. 


Further Explaination and a Practical Example


JavaScript has this thing called scope. As in normal grammar, scope means " the extent of the area or subject matter that something deals with or to which it is relevant. ". In JavaScript, the scope of a variable determines where that variable is available for use. For example if you have a JavaScript file and you simply create a new variable outside of any objects or functions, that variable will automatically be assigned as a property of the window object. The window object is the mother of all other objects, it is the parent of everything in your code. Anything that is a property of the window object is considered global in scope, meaning you can access it from ANYWHERE in your code. 


Then you have local scope. A variable that is local in scope is only accessible inside of its parent object or function. If you declare a variable from within a function, that variable is a local variable and stops existing for any code that is outside of that function. 



Why does this all matter? Because this is a special, magical keyword in JavaScript. The scope of the this variable is dynamic, it depends on where it is used. The this keyword always refers to the current parent object of whatever piece of code is running. If this is used inside of a function then this will refer to the object that is a direct parent of that function. If this is used in a constructor function that is intended for use with the new keyword, then it will refer only to the instance of that new object that is created. 


Take a look at this code from one of the RMMV core files: 


Scene_Item.prototype.createCategoryWindow = function() {
this._categoryWindow = new Window_ItemCategory();
this._categoryWindow.setHelpWindow(this._helpWindow);
this._categoryWindow.y = this._helpWindow.height;
this._categoryWindow.setHandler('ok', this.onCategoryOk.bind(this));
this._categoryWindow.setHandler('cancel', this.popScene.bind(this));
this.addWindow(this._categoryWindow);
};


This is using JavaScript's prototype keyword as well, which I won't even begin to try and explain. It suffices to say that we have this object called Scene_Item. It has a property called createCategoryWindow which is also a function. In JavaScript, functions are objects too and that means they can have properties. 


The Scene_Item function is intended to be used with the new keyword, so it's considered a constructor function. You would use it like this: 


var MyVar = new Scene_Item();


The createCategoryWindow function is not a constructor. It is a child of the Scene_Item class (JavaScript doesn't technically have classes but when you have a function that acts as a constructor, you can treat it like a class, similar to languages like C# and Java). As such, the this keyword in the createCategoryWindow function will refer to the Scene_Item object. In my example, this would refer to MyVar since MyVar is an instance of the Scene_Item class. In case you haven't gleaned it, an instance is a variable  that was constructed with a constructor function. The constructor function (Scene_Item) doesn't do anything by itself, it's purpose is to provide instructions on how to create a new object and what properties it should have. 


When I create MyVar I created a new instance of the Scene_Item class. MyVar has all of the default properties that are part of the Scene_Item prototype, including the createCategoryWindow function! 


We can access the properties of this instance like this: 


MyVar.createCategoryWindow(); // Runs the createCategoryWindow function for MyVar, changes other properties of MyVar.


MyVar now has a property called _categoryWindow which, in itself, is an instance of the Window_ItemCategory class. 


Now that we created that property with the createCategoryWindow function, we can access it like so: 


MyVar._categoryWindow.index = 1;




So the this keyword referred  to the parent object of the function it was inside of. If you use the this keyword outside of an object or function, or inside a function that's just defined in the root of your document, it will refer to the window object. 


Just Because It Can: JavaScript Breaks Its Own Rules


Here are some annoying contradictions to scope and how it works: 


If you define a local variable (inside a function) that has the same name as a global variable, within the scope of that function it will be used instead of  the global version. Once your code stops running inside that function,  the global version will take over again. This can only be done by using the var keyword before the name of the variable. 


var myMessage = "I Am Global!" // Global Variable

function doStuff(){ // Global Function

console.log(myMessage);
}

doStuff(); // Logs "I am Global!"

function doMoreStuff(){ // Global Variable
var myMessage = "I am Local!" // Local Variable with Same Name!!!
console.log(myMessage);
}

doMoreStuff(); // logs "I am Local!"

console.log(myMessage); // logs "I am Global" because myMessage was NOT changed by doMoreStuff().




JavaScript has another thing called closures. A closure basically allows a variable to live outside of its scope. When you use the var keyword inside of a function, you can create other functions within that use that variable and then return them or call them from different places. Even though that variable usually would die outside of it's function, it lives on because it was used in a function that can be invoked later: 


function greeting(name){
var message = 'Hi ' + name; // Local-Only Variable

var greet = function(){ //Local-Only Function
console.log(message);
}
return greet; // We're returning the function so it can be used later!
}

var MyGreeting = greeting("Bob"); // A new variable that is assigned the value of the greet function

MyGreeting(); // Logs "Hi Bob" because the message variable lived on through the greet function's use of it.




I hope that helps!


----


I make a lot of typos so I will probably edit this 50 times. Please be patient. 
 
Last edited by a moderator:

Ellie Jane

Veteran
Veteran
Joined
Mar 17, 2012
Messages
752
Reaction score
1,488
First Language
English (UK)
Primarily Uses
RMMV
Did you begin with another RPG Maker beforehand? It's very similar to self in RGSS.
 

Ultimatony

Veteran
Veteran
Joined
Jan 6, 2016
Messages
72
Reaction score
6
Thanks for all the replies, I'll be reading through them.


No I haven't used any other RPG makers.


Feel free to add anything else you think would help.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
It takes a while for it to really sink in so you might struggle with keyword this for a while. When a function is called the value of this is evaluated. Let's first consider calling a plain old function.


function myFunction() {
console.log("My this value is:", this);
}

myFunction(); //-> My this value is: Window




The ECMAScript specification (JavaScript is an implementation ECMAScript) says that the caller of a function provides a thisArg (Arg is short for Argument) but if thisArg is null or undefined then thisArg will be bound to the global object. Running the above code in a web browser will print out "My this value is: Window" in the console because we didn't specify a value for this.


var myObject = {
myProperty: "Some value"
};

var anotherObject = {
anotherProperty: "Another value"
};

myFunction(); //-> My this value is: Window

myFunction.call(myObject); //-> My this value is: Object { myProperty: "Some value" }

myFunction.apply(anotherObject); //-> My this value is: Object { anotherProperty: "Another value" }

myFunction(); //-> My this value is: Window




We can tell a function what this value to use by calling the function with call() or apply() as seen above. Also demonstrated is that we aren't permanently changing the value of this by using call() or apply().


var myObject = {
myProperty: "Some value"
};

var anotherObject = {
anotherProperty: "Another value"
};

var boundFunction = myFunction.bind(myObject); // Create a new bounded function and assign it to boundFunction

boundFunction(); //-> My this value is: Object { myProperty: "Some value" }

boundFunction.call(anotherObject); //-> My this value is: Object { myProperty: "Some value" }




Using bind() creates a new function that sets a permanent value for this. Calling the function referenced by the variable shows what we expect but trying to be sneaky and changing the value of this using call() fails. A lot has been covered but there are 3 more items to consider.


function myFunction() {
console.log("My this value is:", this);
}

var myObject = {
myProperty: "Some value",
myMethod: myFunction
};

myObject.myMethod(); //-> My this value is: Object { myProperty: "Some value", myMethod: myFunction() }
myObject["myMethod"](); //-> Ditto




Properties can hold references to functions and these functions are known as methods. Calling a method using either dot or bracket notation sets the value of this to the object on the left of the dot or opening bracket.


function myFunction() {
"use strict";
console.log("My this value is:", this);
}

myFunction(); //-> My this value is: undefined




Here's our plain old function again but this time it's in strict mode. Unless a value for this is specified via call(), apply(), bind() or by calling it as method, the value of this will be undefined. It turns out that is super important based on the final topic of this post.


function createMyObject() {
this.myProperty = "My value",
this.myMethod = function () {
console.log(this.myProperty);
}
}

var neoObject = new createMyObject();
console.log(neoObject); //-> Object { myProperty: "My value", myMethod: createMyObject/this.myMethod() }
neoObject.myMethod(); //-> My value


Functions used to create new objects are called constructors. Constructors are called with the keyword new which tells JavaScript to create a new object and then call the function with this set to reference the new object. Calling a strict mode constructor without the keyword new isn't a problem but if we accidentally called createMyObject() without new its this value would be the global object and we would end up adding myProperty and myMethod to the Window object in a web browser which is bad.


Any who, hope that helps some. It sure helped my understanding of keyword this just trying to explain how it works.
 
Last edited by a moderator:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Our latest feature is an interview with... me?!

People4_2 (Capelet off and on) added!

Just beat the last of us 2 last night and starting jedi: fallen order right now, both use unreal engine & when I say i knew 80% of jedi's buttons right away because they were the same buttons as TLOU2 its ridiculous, even the same narrow hallway crawl and barely-made-it jump they do. Unreal Engine is just big budget RPG Maker the way they make games nearly identical at its core lol.
Can someone recommend some fun story-heavy RPGs to me? Coming up with good gameplay is a nightmare! I was thinking of making some gameplay platforming-based, but that doesn't work well in RPG form*. I also was thinking of removing battles, but that would be too much like OneShot. I don't even know how to make good puzzles!
one bad plugin combo later and one of my followers is moonwalking off the screen on his own... I didn't even more yet on the new map lol.

Forum statistics

Threads
106,034
Messages
1,018,446
Members
137,820
Latest member
georg09byron
Top