Using bracket notation on a JavaScript number - javascript

I was reading through code submitted by someone on a coding forum. I came across something like 100[0] in his code. I expected JavaScript to throw an error but to my surprise it is undefined. I have known the bracket notation to be used with objects, arrays and strings but it is quite strange that it doesn't throw when used with a number.
Is this similar to invoking a method on a string literal like "FOO".toLowerCase() where the string is first coerced to an object and then toLowerCase is invoked? Can someone explain to me what is going on here?

While numbers like 12 are primitives in javascript, you can still access properties on it. Take a look at the Number API Reference for what kinds of properties a number has.
For example, (2).toString() will yield '2'. So will 2['toString'](). This should hopefully help explain why such syntax is still valid.
What makes this possible is a technique called "boxing". Most of the time when working with numbers, we aren't accessing properties or methods on the number, so the runtime will just use primitive values to keep things quick. But, the moment we try to access a property like toString() on the number, then a temporary instance will automatically be created for that number so that you can access the property.
This is mostly an invisible process, but artifacts of it are noticeable in the language. For example, comparing two primitives, 2 === 2, is true. But if we force boxing to happen with the Number constructor, new Number(2) === new Number(2), then we'll be comparing two number object, and these objects follow the same rules as any other objects, so this will actually evaluate to false. (Note that we can only observe these kinds of behaviors by force creating the number instances, the auto-boxing will never happen for anything but equality checks).

Related

How Javascript stores methods

Why is it that in Javascript, methods that relate to numbers are stored in the Math object? For example, to round you would need to do Math.round(5.2)
On the other hand, for strings I can just do “hello”.toUpperCase()
Why not String.toUpperCase(“hello”)
Like why cant we do 2.5..round() like how we would do "hello".toUpperCase()
Is there a reason why things are organized this way?
We can't do something like:
2.toString();
directly, but we can:
console.log((2).toString());
This is suspicious to me... so i think javascript convert object literals in a specific generic type, something like String, and then makes the operation that is needed according the String method given.
In your example you said that Math object stores methods for making convenient number transformations, like parsing it to an int, parsing it to a float and etc.
But this is not exactly true, because we have also functions like:
window.parseInt();
window.parseFloat();
that are focused in.
And also we have the generic Number class which allows us to create a generic number as the java Integer which is different of java primitive int, so this clarify a bit what is going on here.
I think javascript have some methods for string and String and also number and Number but they are not the same, one is generic and the other is primitive, but... if this where true, the primitive objects should never have methods, so we can assume three possibilities:
For object literals methods javascript converts the primitive object (if it's a primitive object) to a generic object and uses the generic object method, or uses an static generic class method.
Primitive objects in javascript aren't primitive they are generic.
Primitive objects have been constructed with some attached methods to it.
I will not make a confirmation about what is, because i don't know really if some of these posibilities are the right, but in my opinion i think the first one is the more accurate of how javascript stores and uses object literal methods.

Is there a specific reason why javascript has no isEqual() native function to compare Objects?

The object1 == object2 operation checks to see if the references are the same.
A lot of times we want to check if the objects structure (properties, values and even methods) are the same. We have to implement a isEqual() function for ourselves or use an external library.
Why isn't it just added to the javascript ECMA standard, like JSON.stringify() was?
Is there a specific reason?
For what I can gather, this hasn't been implemented because objects can have very different structures and only in very simple object structures consisting of name:value like obj = {name:"value",age="anotherValue"} the isEqual(obj1,obj2) would be useful.
Although I think it should be implemented nevertheless.
Most probably because there is no obvious way to determine what exactly makes two objects equal.
For example, you could check that they have the same property names with the same values. However,
These values can be objects, should their equality be loosely checked recursively? Then, what should be done with cyclic references?
Should only enumerable properties be checked, or all of them?
Should only string properties be checked, or also symbols?
Should only properties be checked, or also internal slots?
If not all internal slots are checked, which ones? For example, should the [[Prototype]] values in ordinary objects be compared, or maybe call the [[GetPrototypeOf]] method? Should all function internal slots be compared, or otherwise how would you determine function equality?
Should only the property values be compared, or also the configurability, writability and enumerability?
What about accessor properties? Should getters be called and compare the returned values, or compare the getters and setters themselves?
What about proxy objects, which may return a different set of properties each time you ask them?
There is no best answer to these questions. For each person, object equality might mean different things. So they can write a function which checks exactly what they want.

'indexOf' method performance optimization

According to Is JavaScript a pass-by-reference or pass-by-value language? JavaScript passes string objects by value. Because of that, calling the indexOf method will trigger copying the content.
In my case, I am parsing a big string to look for data. I heavily use indexOf to find data. String can big as long as 100-200KB and I could need to call indexOf up to 1000 times per full scan.
I'm afraid this will cause polluting 'memory' with unnecessarily copied string and could impact performance.
Am I correct in my conclusion? If so, what is the proper way to deal with my task?
Potentially, I could use regular expressions, but at the moment that looks too complex.
Strings are a strange beast in Javascript, they seem to inhabit a middle ground between primitive types and objects. While technically they're considered primitive, they can in many circumstances be treated as if they were a reference, due to their immutability.
Given that they are immutable, I'd be very surprised if a copy of the string was passed to any function, since that would be both hideously expensive and totally unnecessary.
A seemingly easy way to find out would be to pass a string to a function and change one of its characters to see if that's reflected in the original string on return. However, as mentioned, the immutability of strings makes that impossible.
It may be possible to test this in an indirect manner by executing indexOf("a") against one of two string in a loop of many million times.
The string to search would either be "a" or "a very long string containing many thousands of characters ...".
If the strings are passed by reference, there should be no noticeable difference in the times. Passing by value should be detectable since you have to copy the string millions of times and a short string should copy faster than a long one.
But, as I said, it's probably unnecessary since the engine will most likely be as optimised as possible.
.indexOf() is merely a search of the string and just returns a numeric index into the string. There is no need to make a copy and no copy is made. This doesn't really have anything to do with value/reference in Javascript. The operation is merely a search that returns an index. There is simply no need to make a copy.
Strings in Javascript are immutable. That means they can never be changed and these indexes into the string always point at the same place in the string. Any operation that operates on a string to make a change, returns a new string leaving the old one.
This allows for some interesting optimizations in the implementation. Because a string is immutable, it can be shared among all points of code that have a reference to it. Whenever anyone calls a function to modify the string, it simply returns a new string object created from the old one plus the modification.
If you were to use the index from .indexOf() with .slice() or something like that, then you would be copying part of the original string into a new string object (likely using some additional memory).
If you want to test this for yourself, feel free to run as many .indexOf() operations as you want on a large string and watch memory usage.

Primitive wrapper behavior in JavaScript

In the book Professional Javascript for Web Developers i read that primitive wrappers are used internally by JavaScript when trying to access properties and methods of primitive objects. Does that mean that each time i try to access the length property on a string primitive the value is recalculated? My gut tells me that since strings are fixed then their length value is stored somewhere and only accessed by the wrapper, but i'd rather be sure.
By specification, yes (§11.2.1, §8.7.1, §9.9, §15.5.5).
Still that does not mean an actual implementation will create string objects in the memory, this is surely optimized.
I think that's true, primitive wrappers are created on the fly when you try to access properties of primitive values, like this:
"foo".length; // behaves as new String('foo').length
Not only the length is calculated on the moment you try to access the property, but a whole new object is created too (that object is what actually contains the property). The wrapper is then discarded immediately.
If you're worried about performance, don't be. There's rarely a case when you must use a primitive wrapper object, and their performance seems to be orders of magnitude slower than just using the primitive values (see test). Let the interpreter care about optimization.

JS Object navigation-- when to use object.sub and object["sub"]?

Looking at this from a point of semantics, there's two ways to navigate objects in JS, you can either use the dot operator or work through them like it's a nested array.
When is it appropriate to use one operator over the other? Why shouldn't I just use the method with square brackets all the time (it seems more powerful)? They both seems easy to read, but the dot operator looks like it's limited in that it cannot be provided with variable names of nested objects, or work through arrays.
The main reasons for using []
You can't access properties with the names of keywords via the dot notation (at least not in < ES5)
You can use it to access properties given by a string
The reasons for using .
Always using [] makes syntax highlighting, code completion etc. pretty much useless
Even with automatic insertion of the closing counter parts [' is a hell lot slower to type (especially on non US Keyboard layouts)
I mean, just imagine writing Chat['users']['getList']()['sort']()['each'].
Rule of thumb: Use . where ever possible, and fall back to [] when there's no other way.

Categories

Resources