# Javascript Woes

Discussion in 'Learning Javascript' started by Solistra, Aug 11, 2015.

1. ### SolistraVeteran

Messages:
593
241
// Let's do some math.true + true; // => 2[] + []; // => ''[] + {}; // => '[object Object]'{} + []; // => 0{} + {}; // => NaN2 / false; // => Infinity/* Also, always remember that both strings and numbers have a binary `+` * operator, and implicit conversions to and from each happen *all the time*. * Really, this can and _will_ cause headaches at some point. */'1' + 1 // => '11''3' * 2 // => 6/* Since we're on the topic of numbers and math, Javascript gives you 53-bit * numbers. Have fun with this: */Math.pow(2, 53) == Math.pow(2, 53) + 1; // => true/* But Javascript is totally consistent -- and don't let anyone tell you * otherwise: */null == 0; // => falsenull > 0; // => falsenull < 0; // => falsenull >= 0; // => truenull <= 0; // => truetypeof NaN // => 'number'typeof null // => 'object'null instanceof Object // => false3 > 2 > 0 // => true3 > 2 > 1 // => false[] == false // => trueif ([]) { console.log('Really?'); } // => 'Really?'if (new Boolean(false)) { console.log('Seriously.');} // => 'Seriously.'// Modulus operations are *completely* inaccurate:-7 % 4; // -3// Let's fix that.Number.prototype.mod = function(n) { return ((this % n) + n) % n;}/* Now we have to do modulus operations in any of the following ways (since we * can't overload the default `%` operator): */(-7).mod(4); // => 1-7 .mod(4); // => 1-7..mod(4); // => 1// Except this one, because it's a syntax error:-7.mod(4);/* Also, division by zero results in infinity, while modulus operations with * zero result in "not a number." In any sane language, both would be errors. * Especially when it comes to _game development_. */2 / 0 // => Infinity2 % 0 // => NaN// Sorting numerical arrays, by default, is nonsense:[1, 300, 5, 10, 2].sort(); // => [ 1, 10, 2, 300, 5 ]// So you have to do this every time instead:[1, 300, 5, 10, 2].sort(function(a, { return a - b;}); // => [ 1, 2, 5, 10, 300 ]/* Sorting using a function like that creates a new function every time you * want something sorted, though, so you might just want to define some utility * function that you can pass into it. Say hello to reinventing the wheel * another 5,000 times. * * Oh, and if you want to actually _compare_ arrays, you'll need to create that * functionality yourself. Here's a ludicrously simple example that doesn't * actually work for anything even remotely complex or unusual: */function arraysEqual(a1, a2) { // Don't use `for (x in y)`-style loops over arrays. They're extremely slow // and greedy. I'm serious. for (var i = 0; i < a1.length; ++i) { if (a1 !== a2) return false; } return true;}/* By the way, you almost always want to declare variables with `var`: if you * don't, they leak into the global scope. Surprise! */function leak(a, { r = a + b; return r;}leak(5, 5);r; // => 10/* At the same time, always declaring variables with `var` can also cause some * really bizarre behavior. Surprise! */var scope = 'global';function timeTravel() { console.log(scope); var scope = 'function';}timeTravel(); // => undefinedYeah, start learning Javascript and its exceedingly bizarre eccentricities. Also, try to avoid using == unless you like the complex, nonsensical logic behind type coercion. Take a look at this: The Abstract Equality Comparison Algorithm. Get back to me when you have that memorized. (Oh, == is actually useful for checking for null and undefined, though, which are two separate things -- so remember to use it for those. And NaN isn't equal to anything, even itself, so check for those with isNaN(object); or perish.)Honestly, I didn't even begin going into the strange behavior of Javascript's variable bindings with closure semantics or how you can even get something as simple as a stack trace in a reliably cross-platform way. (There are third-party libraries that can get you a stack trace, but every one of them has its own assortment of bugs. Irony.)

By the way, firing your game up in a web browser to check it is nice and all, but don't forget that Javascript implementations vary significantly across browsers, and what works in one may either break completely or just leak subtle, hard-to-track bugs into your game in another.

Good luck with MV, everyone. I'm actually being completely serious there -- normally, that would have been sarcastic, but really, I wish you all luck. I'm not touching this version. My only real advice to the scripting community is this: come together, stop reinventing everything, and code defensively. The Javascript library landscape is extremely fragmented because no one can ever agree on the same ways of doing anything; even simple acts like "how to define a class" (prototype, really, but you know what I mean) can be extremely fragmentary (which means it can get tricky trying to determine what an object actually is depending on how it was defined).

Again, come together. All of you. Teach each other, admit your mistakes, and learn from them. Ironically, though, I'm leaving the community after this post, so... I wish you all luck.

Goodbye.

Marsigne, Mimironi, Evgenij and 14 others like this.
2. ### RamiroNow with an army of Mecha-Ralphs!

Messages:
860
366
Location:
Argentina
First Language:
Spanish

I am having so much fun with this, just because its true.

'%' is not the absolute module, it is the arithmetic modulo, often called remainder, the modulo is defined to satisfy this in javascript:

floor(a / * b + a % b == a // must be trueOf course, you can get ruby's modulo with this:

(a % b + % bBut yes, you should be so carefull with types in javascript.

Not really a problem in real life too often anyway.

Then download the game's pc version and not use the html one

For multiplayer online games, (I doubt an MMO could work like a 'MM' for now...) streaming content via html5 is awesome.

You can use session storage AND streamline at the same time in html5, so its a yes-yes for streamed resources

Last edited by a moderator: Aug 11, 2015
3. ### HudellDog Lord

Messages:
3,315
2,922
Location:
Brazil
First Language:
Portuguese
Primarily Uses:
RMMV
2 - 0.1 - 0.11.7999999999999998

4. ### GalenmerethI thought what I'd do was

Messages:
2,206
1,911
Location:
Norway
First Language:
English
Primarily Uses:
RMMV
Re: Solistra's post: All of this is true, which is why I mentioned earlier the degree of pain the language can cause. However, it's also been around the block so many times now that there's solutions for all of it. And yes, solutions are fragmented, and how the scripting community embraces this will be very interesting. For example, a common solution to a ton of JS's problems is underscore.js: http://underscorejs.org/

But if I distribute a script using this, I need to require the end user to also include it. And the correct version, should there be new ones. And then someone else uses a different solution. And then we have a cluster cluck. But we can figure out a good solution for everyone. Although at first uncertain, I intend to stick around. See you in the trenches scripters. o7

Point08, Marsigne, ?????? and 5 others like this.
5. ### EnelvonSlumbering Goddess

Messages:
240
134
Location:
Dreamland
First Language:
English
The problem with your statement is that modular arithmetic is based on Euclidean division, and negative remainders are forbidden. What you call "Ruby's modulo" is, in fact, the actual modulo that you would use when doing actual math in the actual world rather than in the Lovecraftian fever dream that is Javascript.

Edit: I would like to note that I am very much aware that different languages often choose to use the sign of either the divisor or the dividend for the remainder, with Ruby's implementation using the divisor (so `-6 % 4` would return 2, while `6 % -4` would return -2). This does not change the fact that in number theory and applied mathematics (outside of writing code) you will almost always be working solely with positive remainders when doing modular arithmetic. My reply was based on your explanation of the nature of the modulo, and has nothing to do with programming itself (outside of a reference to Ruby's modulo, which you spoke about yourself and would give the proper mathematical result in Solistra's example). I simply wished to correct a misconception.

Last edited by a moderator: Aug 11, 2015
AwesomeCool and ♥SOURCE♥ like this.
6. ### AwesomeCoolBratty and spoiled little sister

Messages:
2,877
1,953
Location:
Behind you! BOOOO!
First Language:
English
Primarily Uses:
N/A
@Solistra - I hope the majority of scripters work together,  although the crediting is probably going to get messy.

I also hope people spread out more in terms of scripts made for MV.  Looking back at vx ace, many side view battle systems were made/attempted and most of them didn't really offer anything different from what was already out there.  Alternatives are nice, but not when there are so many that do not do anything different then the previous ones.  Also, I only ever even seen about 3-4 side view battle systems ever used in rpg maker vx ace games despite so many that were made.

Also, a bunch of atb battle systems were made.  This bugs me due to ftb and atb were the only to battle systems available for vx ace for more then half of its life (I might of missed one).  ctb scripts are still rare and the first publicly available press-turn system came out less then a year ago for vx ace.

Again, I love alternatives to scripts already made, but if they do not offer something different then what is currently out there, then one script will bury the other into obscurity.

And I don't think any scripter wants there script to not be used when they put so much work into it.

Point08, Marsigne and nio kasgami like this.
7. ### Lecode(─‿‿─)

Messages:
490
646
First Language:
French
Primarily Uses:
N/A
[] == false // => trueif ([]) { console.log('Really?'); } // => 'Really?'// -------------------------------------------var scope = 'global';function timeTravel() { console.log(scope); var scope = 'function';}timeTravel(); // => undefined . Javascript is creepy.

8. ### Yuuta KirishimaSoftware Engineer/Professional Mayonnaise Player

Messages:
550
131
Location:
North Carolina
First Language:
Engilsh
Primarily Uses:
RMMV
Here's a setup of a very old Text Based RPG I created:

var Player = function(hp, def, att, spa){ this.hp = hp; this.def = def; this.att = att; this.spa = spa;}This is your "class"

it basically operates similar to the way classes work in ruby

here's an example of a ruby class

class Player attr_accessor :hp; :attack; :defense; :weapon; def initialize(hp, attack, defense, weapon) @hp = hp @attack = attack @defense = defense @weapon = weapon endendnotice the similarities?

This is how you would create an object from said class

Javascript:

var user = new Player(225, 5, 5, 5);You could then call data from that object and even update it:

calling data from said object

if(user.hp > 0){ user_is_alive = true}updating it

if(poisoned == true){// ignore this line step(){ user.hp -= 1 }}This is basic class referencing, javascript is much more advanced but this is some of its more simple aspects.

9. ### KaelanVeteran

Messages:
761
434
Location:
Seattle, USA
First Language:
Portuguese
Primarily Uses:
N/A

10. ### taarna23Marshmallow Princess

Messages:
2,349
4,629
Location:
First Language:
English
Glad to see I'm not the only one that thought of linking this! But I was at work and didn't really want to go rummage around at the time.

11. ### Dr.Yami｡◕‿◕｡

Messages:
994
736
Location:
Finland
First Language:
Vietnamese
Primarily Uses:
Other
All of your said are almost true, though I don't think the problem of engine is the programming language itself. I agree that JS is suck to work with, I had some nightmare with JS before so I know your feeling.

Anyway, about the fragmentary thing, I don't think it's really a problem. The ways to do things depend on the developers, it's a good thing to have many choices for them, though people almost always follow one or two convention(s), it's the same with all programming languages, not only JS.

About the dependencies, there are so many libraries out there and many of them do the same thing. It's up to developers to work with libraries that support their works. I have seen so much "reinvent the wheel" from XP, VX and VXA, but it was not because the developers wanted to do it, it was for users in community could use the features they wanted with ease of use. I don't know if everyone here want to copy tons of libraries just to use a few scripts they want.

In conclusion, I think the problem there is how people deal with new engine, new language and new way of thinking. JS may be uglier than Ruby in some ways, but if MV really supports browsers, we will have a better debug tool (something RMVXA lacks of) and get use to the huge open source libraries written in JS.

Marsigne, Archeia, muramasa and 2 others like this.
12. ### Mister.RightVeteran

Messages:
249
83
Yeah, JS is confusing when your background was another OOP. I learnt Java before JS, so when I learn JS, a lot of things were confusing  at first. In this exmaple

'1' + 1 // => '11'

The + operator here acts as concatenation string. So a String concatenate to a number JS will convert a number to String so you get '11' instead of 2.

----------------

if (new Boolean(false)) {

console.log('Seriously.');

} // => 'Seriously.'

JS has 5 primitive types (number, string, boolean, null, undefined) and reference type. boolean is primitive type and each primitive type (except null and undefined) has a wrapper type associated and wrapper type is reference type. So when you write  new Boolean you are creating reference type, not primitive type.

The example above if statement is actually checking for object instead.

var eventSwitch = new Boolean(false);

console.log(typeof eventSwitch);      //object

var eventSwitch2 = false;

console.log(typeof eventSwitch2);      //boolean

It is best to avoid creating wrapper type because JS automatically created wrapper type for you. For example;

var playerName = 'Ralph';

var firstChar = playerName.charAt(0);

Because primitive type is not reference type here you are using wrapper type String method.  Behind the scene, JS does this.

var playerName = 'Ralph';

var firstChar = playerName.charAt(0);

var temp = new String(playerName);

firstChar = temp.charAt(0);

temp = null;   //deference temp

This is called 'autoboxing'

There 's a book called Object Oriented Javascript which is good book.

Last edited by a moderator: Aug 11, 2015
13. ### Yuuta KirishimaSoftware Engineer/Professional Mayonnaise Player

Messages:
550
131
Location:
North Carolina
First Language:
Engilsh
Primarily Uses:
RMMV
There should be a Javascript Tutorial section, this is getting a bit flooded with Javascript guides.

Zeriab and Rukiri like this.
14. ### kevm3Warper

Messages:
2
2
First Language:
English
Most of those are edge cases. Nobody who programs in a sane manner will have to worry about most of them. If you want classes, just use ES6 and 'transpile' back to older versions if necessary using Babel.

var scope = 'global';function timeTravel() {console.log(scope);var scope = 'function';}timeTravel(); // => undefined
All that is happening here is that you are redeclaring the variable 'scope' inside the function, so that the function timeTravel has it's own variable named scope. Variables in JS are scoped to the nearest function and the declaration is hoisted, but not the i

initialization. So essentially, the code really bets interpreted as:

Code:
var scope = 'global'; function timeTravel(){var scope;  // has a value of undefined console.log(scope);scope = 'function'}

Marsigne likes this.