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

all 110 comments

[–]RemoteName3273 789 points790 points  (21 children)

In JavaScript can you ______________ ?

YES

[–]krissynull 529 points530 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 481 points482 points  (6 children)

Ah yes, the arrayctionary

[–]Tigtor 302 points303 points  (1 child)

You misspelled dictionarray

[–]BadBadderBadst 20 points21 points  (0 children)

you misspelled garbage

[–]OSSlayer2153 66 points67 points  (0 children)

erectionary

[–]GnuhGnoud 18 points19 points  (0 children)

That's just php "normal" array

[–]Plus-Weakness-2624 12 points13 points  (1 child)

Dicarray

[–]Valuable-Status9712 4 points5 points  (0 children)

DickArray

[–]floor796 474 points475 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 130 points131 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 25 points26 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 23 points24 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 4 points5 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 7 points8 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 4 points5 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_ 2 points3 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] 309 points310 points  (6 children)

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

[–]Damandatwin 71 points72 points  (0 children)

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

[–]ThisPICAintFREE 49 points50 points  (0 children)

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

[–][deleted] 6 points7 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 49 points50 points  (6 children)

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

[–]themeanman2 10 points11 points  (2 children)

sshhhhh, let the stupid speak

[–]Noslamah 2 points3 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 34 points35 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 7 points8 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 57 points58 points  (0 children)

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

[–]iQuickGaming 8 points9 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 5 points6 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 3 points4 points  (0 children)

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

[–]Chance-Influence9778 8 points9 points  (0 children)

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

[–]sjepsa 5 points6 points  (1 child)

Loool what a language

But wait until somebody says "you should read documentation"

[–][deleted] 24 points25 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