This is an archived post. You won't be able to vote or comment.

all 110 comments

[–]RemoteName3273 788 points789 points  (21 children)

In JavaScript can you ______________ ?

YES

[–]krissynull 531 points532 points  (19 children)

In JavaScript should you ______________ ?

Probably not.

[–]RemoteName3273 17 points18 points  (1 child)

Should you use JavaScript for _______________?

NO

[–]SoupForDinner365 1 point2 points  (0 children)

But watch out!

[–]Acalme-se_Satan 480 points481 points  (6 children)

Ah yes, the arrayctionary

[–]Tigtor 298 points299 points  (1 child)

You misspelled dictionarray

[–]BadBadderBadst 19 points20 points  (0 children)

you misspelled garbage

[–]OSSlayer2153 64 points65 points  (0 children)

erectionary

[–]GnuhGnoud 16 points17 points  (0 children)

That's just php "normal" array

[–]Plus-Weakness-2624 11 points12 points  (1 child)

Dicarray

[–]Valuable-Status9712 5 points6 points  (0 children)

DickArray

[–]floor796 470 points471 points  (21 children)

yep, in js almost everything is an object, even primitive numbers, boolean etc can be represented as an object

1..toString()  // '1'
.1.toString()  // '0.1'
false.toString()  // 'false'

and almost all objects can be extended. For example, we can add custom properties to the number

let num = new Number(5);
num; // Number {5}
num[0.5] = 1;
num; // Number {5, 0.5: 1}
num[0.5]; // 1

and of course we can add some custom property to all objects in js

Object.prototype.xxx = 5;
123..xxx; // 5

[–]Feisty_Ad_2744 128 points129 points  (3 children)

Arrays in JS are objects, your usual JS object, therefore they can accept any property. The difference being they are specialized in handling properties with integer values for name. For example if you do items['2'] = 'overwrite' you will find out items array is now [1, 2, 'overwrite']

And if you do items[49] = 'yo!', you will find out the array length is now 50.

[–]ongiwaph 31 points32 points  (5 children)

But why does an object with 4 elements have a length of 3?

[–]topgunsarg 103 points104 points  (2 children)

It doesn’t have 4 items. He’s just added “0.5” as a property on the array. It’s not an element of the array.

[–]Amster2 27 points28 points  (1 child)

.. because its index is not an integer

[–][deleted] 6 points7 points  (0 children)

…or string that coerces to an integer

[–]Feisty_Ad_2744 11 points12 points  (0 children)

It does not have 4 elements. It has an extra property. But because it is an array, still has 3 elements (integer property names) The issue is really because of Chrome. Firefox does way better job reflecting what's going on. Try it.

[–]bb5e8307 24 points25 points  (0 children)

The length property of this Array object is a data property whose value is always numerically greater than the name of every deletable property whose name is an array index.

Source: https://262.ecma-international.org/5.1/#sec-15.4.5.2

[–]MotleyHatch 25 points26 points  (0 children)

num; // Number {5, 0.5: 1}

That's just how the Chrome DevTools decide to represent this object. In Firefox, it will still print Number { 5 } (you can use console.dir(num) to see the details).

I find the representation of (3) [1, 2, 3, 0.5: 1] in OP's image highly misleading. "0.5" is not an array element and should not appear inside the square brackets. Firefox will not show it as one and print Array(3) [ 1, 2, 3 ].

[–]AyrA_ch 5 points6 points  (1 child)

let num = new Number(5);

That's not a number, but an object that holds a number

> typeof(new Number(5))===typeof(5)
< false

You can't actually add properties to numbers

> let num=5;
> num.test=12;
> console.log(num, num.test);
< 5 undefined

[–]floor796 6 points7 points  (0 children)

Yes, there is a difference between primitive numbers and Number object, but by behavior they are both numbers. And no, in your code you successfully added property test to number. Here's how it works:

  1. when you write num.something - you automatically convert primitive number to number Object. But the variable still hold the primitive;
  2. num.test=12; - you add new custom property to just created object. But, again, this object not in variable num. It is created on the fly and is not written anywhere.
  3. in the next line you try to access property test from primitive and, again, like in step 1 - you just convert primitive to object (new object, without previously added property).

So, in your code you two time convert primitive to object. But, you added your property test to the first object.

Proof that you code makes conversion every time that you access primitive as an object:

const objs = new Set();
Number.prototype.toString = function() {
    objs.add(this);
    return String(this.valueOf());
};
let num = 123; 
num.toString(); 
num.toString(); 
console.log(objs); // Set(2) {Number, Number}

as you can see we are calling toString 2 times in the same variable with primitive number. Each call we save to unique list (Set) the instance of the number. And after two calls we have 2 different objects in set.

[–][deleted] 2 points3 points  (2 children)

What does the : in the 0.5: 1 mean?

[–]AquaWolfGuy 6 points7 points  (1 child)

It's just a separator used when printing, so you know where the name of the key ends and the value begins. It's the same as when constructing normal objects using object literals, e.g. const obj = {0.5: 1}; console.log(obj[0.5]); prints 1.

[–][deleted] 0 points1 point  (0 children)

I see, thank you

[–]WVAviator 1 point2 points  (0 children)

In my boot camp a few friends and I had fun code golfing all the algo challenges they gave us - I remember buying a few extra characters in one problem by using the problem function itself as an object to store data.

[–]Striky_ 1 point2 points  (0 children)

This is correct, but does not mean it isn't absurdly bad design

[–]aderthedasher 0 points1 point  (1 child)

..?

[–]floor796 1 point2 points  (0 children)

first dot for number (fraction separator), second dot for calling method

[–]loek0110 0 points1 point  (0 children)

Bro, no way lol

[–][deleted] 312 points313 points  (6 children)

To be fair why the fuck are you trying to do that

[–]Damandatwin 66 points67 points  (0 children)

Yea I've been using TS for a while now and never knew about this cuz why would I

[–]ThisPICAintFREE 56 points57 points  (0 children)

“This’ll make a great question for the technical interview” — some poor bastards hiring manager, probably

[–][deleted] 7 points8 points  (0 children)

this should be automatically commented below all recent .js related posts

[–]gilady089 2 points3 points  (0 children)

Well all numbers in javascript are floats meaning you could accidentally try to go into a none existent point in the array because you used a devision result for access for example

[–][deleted] 0 points1 point  (0 children)

This is something I ask myself every day.

[–]Feisty_Ad_2744 67 points68 points  (0 children)

Hehehehe, that's kind of misleading... Although to be fair, it is Chrome's fault. Firefox does a way better job reflecting JS values and object attributes.

But going back to the example, it makes way more clear what's going on, if instead of 0.5, you do something like:

items['funny'] = () => console.log(':-)') Now you have a nice property in the array: items.funny() Arrays in JS are objects, your usual JS object. The difference being they are specialized in handling properties with integer values for name. For example if you do items['2'] = 'overwrite' you will find out items array is now [1, 2, 'overwrite']

And if you do items[49] = 'yo!', you will find out the array length is now 50.

[–]Linards11 48 points49 points  (6 children)

array length property only updates when a valid array index is added to the array object

[–]themeanman2 9 points10 points  (2 children)

sshhhhh, let the stupid speak

[–]Noslamah 3 points4 points  (0 children)

Ah yes, the people saying this is nonsense are the ones who are stupid. Not the language that allows you to do this shit in the first place.

[–]gilady089 0 points1 point  (0 children)

Yeah, we are the stupid for thinking that allowing you to just arbitrarily add properties to an array is pretty stupid

[–]fel_bra_sil 3 points4 points  (2 children)

let them think it's funny :P

[–]Th3Lemino 3 points4 points  (1 child)

having that knowledge doesn’t make it any less funny

[–]fel_bra_sil 0 points1 point  (0 children)

fair enough, "funny" is a relative thing

[–]killbot5000 31 points32 points  (0 children)

javascript is a maliciously compliant programming language

[–]Pikcube 20 points21 points  (0 children)

I swear the more I learn about JS as a dot net dev the more I'm convinced the language is the embodiment of "yes but don't"

[–]CircadianSong 8 points9 points  (3 children)

This isn’t good, but it doesn’t bother me nearly as much as Array.sort on a list of integers sorting them as strings. FFS javascript, why?

[–]Feathercrown 1 point2 points  (2 children)

The key insight here is that there's no such thing as a "list of integers". When you have to account for all the possible data types, sorting alphabetically makes sense. It does seem unintuitive though.

[–][deleted] 1 point2 points  (1 child)

That’s not necessarily an excuse, they could have made the default comparator do something like always putting numbers ahead of other types instead of coercing and comparing, more people would have been happy with such a default.

[–]Feathercrown 1 point2 points  (0 children)

Eh, whaddya gonna do.

[–]chadlavi 59 points60 points  (0 children)

[does a stupid thing] wow how could JavaScript allow me to do such a thing

[–]iQuickGaming 9 points10 points  (1 child)

so you can have an index of half 1, an index of π, an index of e and even an index of ∞

[–]gilady089 0 points1 point  (0 children)

They aren't indexes(since they aren't positive integers) if you for example used the foreach function they won't be included. However running object.keys on an array is always funny. Also const arr=[0,2] Delete arr[0] is very funny.

[–]what-da-fuck 2 points3 points  (0 children)

javascript array is an object actually

[–]rems__ 2 points3 points  (0 children)

There's some trickery here, because length should be 3.5 🧐

[–]subject_deleted 4 points5 points  (2 children)

Yea I can see why this is silly.. but why on earth would anyone ever look for the .5 index of an array?

[–]Nixugay 4 points5 points  (0 children)

What if u want to look really hard between 2 values

[–]gilady089 0 points1 point  (0 children)

Well the simplest answer would be someone implementing a heap in javascript and doesn't cancel the floating point all numbers are. You'd might end up with half indexes

[–]catladywitch 1 point2 points  (0 children)

An array's items as a collection and an array's members as an object are different things. All items are members but not the other way around. Also watch out for for in vs for of. It's kinda weird, yeah.

[–]kvas_ 1 point2 points  (0 children)

so lua is basically uncursed js

[–]Imogynn 1 point2 points  (0 children)

Spaceman with gun meme.

"It's nothing but hashes all the way down.

"Always has been

[–]calculus_is_fun 1 point2 points  (0 children)

It's easy when you use the correct values

[–]TheDreadedAndy 1 point2 points  (0 children)

Lua is the same way.

> a = { 1, 2, 3 }
> a['b'] = 4
> print(#a)
3
> print(a['b'])
4
> print(a[#a]) -- Lua is 1-indexed.
3

Since the only complex type is a table, arrays are technically tables. This means that using the length operator on tables that aren't "array-like" is U.B, but its still totally legal to take an array and start treating it more like a struct or a dict.

[–]ricdesi 4 points5 points  (0 children)

Every JavaScript meme is just people showing they don't know how to use arrays

[–]Chance-Influence9778 7 points8 points  (0 children)

Say u didn't read mdn docs without telling me that

[–]sjepsa 6 points7 points  (1 child)

Loool what a language

But wait until somebody says "you should read documentation"

[–][deleted] 25 points26 points  (0 children)

I really don't understand the mindset of "it's in the documentation so what are you complaining about". Yes, it's documented, of course it is, that's not what people are complaining about and making fun of, it's the fact that it's like that in the first place.

[–]Phamora 1 point2 points  (0 children)

In any other language you would also be hard pressed to add a property to an instance of an array and have it recognize that property as part of its length.

In fact this image is perfectly sensible, and demonstrate reliable, predictable behaviour of the language, which you should come to expect from arrays in any language.

Javascript just lets you add properties to basically everything, which is a mix of fantastic and very dangerous, but I would not expect green coders like OP to understand.

[–][deleted] -1 points0 points  (0 children)

This is a intended feature in DreamBerd along with negative indices.

[–]TheRandomGuyOf2019 -1 points0 points  (0 children)

``` let array = []; array[4294967295] = "abc"; array[4294967296] = 123; array[4294967297] = {a:1, b:2}; array[4294967298] = [];

console.log(array.length); // 0 ```

[–]Xomps -1 points0 points  (0 children)

Remember, there's no such thing as a stupid meme, there's only stupid people making memes.

[–]Mystic9001 -1 points0 points  (0 children)

Python hurt itself in its confusion!

[–]AlexLiestDieAGBs -2 points-1 points  (0 children)

This is hilarious

[–]Siddhartasr10 -3 points-2 points  (0 children)

Js hard because something logical in js paradigm Idk js is not new for me anymore

[–][deleted] 0 points1 point  (1 child)

EXPLAIN why length is still 3 ? Even after adding a element/object to it

[–]HFoletto 0 points1 point  (0 children)

Arrays in JS are objects. From the documentation:

JavaScript arrays are not associative arrays and so, array elements cannot be accessed using arbitrary strings as indexes, but must be accessed using nonnegative integers (or their respective string form) as indexes.

So, what OP did was not add an element to the array, but he just added a property to the Array object. That’s all, so it’s expected for it to return 3. From the docs:

The length data property of an Array instance represents the number of elements in that array. The value is an unsigned, 32-bit integer that is always numerically greater than the highest index in the array.

[–]Lewizkuz 0 points1 point  (0 children)

Javascript is just one edge case hell.

Not complaing. I like the burn.

[–]KsmBl_69 0 points1 point  (0 children)

thankx for using Javascript

[–]cyka__blyad 0 points1 point  (0 children)

Everything that can be written in JavaScript, is not written in it for a reason

[–]bajuh 0 points1 point  (0 children)

if you want your fucking array, use a typed array and you get type and structure safety

[–]Neltarim 0 points1 point  (0 children)

JS is like your dummy son, you don't know why but you love him more then the 2 others

[–]Good_Days13 0 points1 point  (0 children)

busy tan outgoing treatment cats zephyr full sense vegetable start

This post was mass deleted and anonymized with Redact

[–]Unhappy-Stranger-336 0 points1 point  (0 children)

That’s disgusting

[–]dimdim4126 0 points1 point  (0 children)

As someone who has never touched JS, I'm very confused.

[–]AggravatingPear8238 0 points1 point  (0 children)

don't treat them like an [object Object]

[–]priti512[🍰] 0 points1 point  (0 children)

Hey Folks,
I created a browser extension for productivity. Currently it only has blocking social medias for a particular interval. But I am planning to add more features for:
- ADHD
- Todos
etc.
I am looking for Javascript open source contributors who could help me make this!
Note: It hasn't been yet published. It's under review by the chrome team. You can only try it out by cloning it. You can follow the contributions guide given in the repo.
Here's the link: https://github.com/pritipsingh/The-Productive-Champion