Does javascript store variable names? - javascript

let num = 10;
console.log(num);
For example, if the value 10 stored at 0x123..
How does javascript recognize that the string "num" is associated with the address 0x123.. which contains the value 10?
I found an explanation about this process in C, basically the compiler discards the name and substitutes it with the address (the name of the variable is not preserved). Is it the same for javascript?
I am confused because javascript is different, it's just-in-time compiled. Every browser vendor probably implements their own version of this but I imagine that they share the same concepts.
Does this mean that it maintains a symbol table at all times to keep track of the relationship between the variable name and its address location?
I skimmed through the ECMA specs and read the MDN documentation and I am still lost.

Related

Are JS primitives references?

I have found explanations that primitives and references get stored directly on the stack (static memory - size of the values is known), whereas objects, functions, etc get allocated on the heap (dynamic memory - to be able to grow).
Source:
https://felixgerschau.com/javascript-memory-management/
Now I've read a few articles where the wording suggests that everything in JS is accessed by reference.
https://daveceddia.com/javascript-references/
So this would mean that primitives are also stored as reference. Is any value stored directly on the stack after all? Another indication is that if you write something like
// no prior variable definition
console.log(a);
// ReferenceError: a is not defined
it will actually give you a ReferenceError, although it could be any type (including primitives).
So, it seems to me like everything in JS is a reference. Is that correct? If yes - where is a referenced primitive value stored? On the heap? On the stack (as it is a primitive)? Can a reference point to the stack?
I want to share the results of my research in case someone else finds it interesting as well.
While the ECMA specification does not seem to be specific (it is also hard to read from a users point of view), there is plenty of information how V8 (Chromium / NodeJS) handles this matter:
It basically puts everything on the heap and references it with a pointer, except for small integers. Small integers are baked into the pointer with a technique called pointer tagging (encoded in the last bits).
Here's what the V8 developer blog says about this topic:
https://v8.dev/blog/pointer-compression#value-tagging-in-v8
JavaScript values in V8 are represented as objects and allocated on the V8 heap, no matter if they are objects, arrays, numbers or strings. This allows us to represent any value as a pointer to an object.
Many JavaScript programs perform calculations on integer values, such as incrementing an index in a loop. To avoid us having to allocate a new number object each time an integer is incremented, V8 uses the well-known pointer tagging technique to store additional or alternative data in V8 heap pointers.

What is the internal data-types in V8 Compiler

While using the heap-stats tool for V8, I found that the memory is represented by some internal terms (possibly the V8 representations) under the JS sections.
Where can i find the descriptions of what are these?
Also, what do these represent?
SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE and SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE under Code section. Are these my source code? Why are they represented in 2byte and 1 byte type separately?
The data types under JS section.
Is there any documentation to find out what datatypes (in JS) they represent?
Where can i find the descriptions of what are these?
They're "instance types", and they're essentially the way V8 distinguishes different types of (internal) objects on its heap. Being an internal implementation detail, they're not publicly described or documented. They can (and do!) change at any time, and unless you work on V8, you're not supposed to have a reason to care about them. They're defined here and here.
SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE and SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE under Code section. Are these my source code?
Yes.
Why are they represented in 2byte and 1 byte type separately?
Special-casing one-byte strings is a memory-saving optimization.
The data types under JS section. Is there any documentation to find out what datatypes (in JS) they represent?
No, but in most cases it should be pretty obvious from their names, e.g. JS_ARRAY_BUFFER_TYPE is for ArrayBuffer objects.
data-types in V8 Compiler
To be nitpicky: this doesn't have anything to do with the compiler; it's a part of the internal object model.

Why does V8 use 4 bytes to represent a JavaScript boolean value, whereas a string character is only 2 bytes? [duplicate]

Is a boolean stored as a 32-bit integer in memory? How about a null value?
In the book Speaking Javascript,
it refers to a type tag being used to indicate the type of a value stored in memory. e.g. The type tag for Object type was 000. What is a type tag?
How would I find the type tag of a value type such as a boolean or string?
From Andy Wingo's blog post on the topic:
Initially, all JavaScript implementations used tagged pointers to represent JS values. This is a old trick that comes from the observation that allocated memory takes up at least 4 or 8 bytes, and are aligned in such a way that the least significant bit or three will be zero.
So the type tags allow for all values to be stored uniformly. All values occupy one machine word (32/64 bit) and depending on the tag (which is the least significant bit or bits) they are interpreted either as a pointer to an object or as some integer/boolean/etc depending on the tag.
is boolean stored as a 32-byte integer in js memory?
A boolean also occupies one word. For a more specific answer I'd need to go though the v8 source. But if I remember correctly, true and false are represented as root pointers.
how to get the type tag of a value type(boolean,undefined,string, number);
No way to do it from JavaScript. It's internal implementation details.

How JavaScript internally recognize the datatype of variable using var? [duplicate]

This question already has answers here:
How does Javascript know what type a variable is?
(4 answers)
Closed 5 years ago.
In JavaScript the keyword var is used to declare a variable. How does the JavaScript Engine parse it and recognize the datatype of that variable?
The variable’s data type is the JavaScript scripting engine’s interpretation of the type of data that variable is currently holding. A string variable holds a string; a number variable holds a number value, and so on. However, unlike many other languages, in JavaScript, the same variable can hold different types of data, all within the same application. This is a concept known by the terms loose typing and dynamic typing, both of which mean that a JavaScript variable can hold different data types at different times depending on context.
With a loosely typed language, you don’t have to declare ahead of time that a variable will be a string or a number or a boolean, as the data type is actually determined while the application is being processed. If you start out with a string variable and then want to use it as a number, that’s perfectly fine, as long as the string actually contains something that resembles a number and not something such as an email address. If you later want to treat it as a string again, that’s fine, too.
you can read this link
all about javascript variables and types
I hope it will be helpfull

Is JavaScript an untyped language?

I've found that some people call JavaScript a "dynamically, weakly typed" language, but some even say "untyped"? Which is it really?
JavaScript is untyped:
(source: no.gd)
Even Brendan Eich says so. On Twitter, he replied to a thread that linked to this question:
... academic types use "untyped" to mean "no static types"...
So the problem is that there's a few different definitions of untyped.
One definition has been talked about in one of the above answers - the runtime doesn't tag values and just treats each value as bits. JavaScript does tag values and has different behaviour based on those tags. So JavaScript obviously doesn't fit this category.
The other definition is from Programming Language Theory (the academic thing that Brendan is referring to). In this domain, untyped just means everything belongs to a single type.
Why? Because a language will only generate a program when it can prove that the types align (a.k.a. the Curry-Howard correspondence; types are theorems, programs are proofs). This means in an untyped language:
A program is always generated
Therefore types always match up
Therefore there must only be one type
In contrast to a typed language:
A program might not be generated
Because types might not match up
Because a program can contain multiple types
So there you go, in PLT, untyped just means dynamically typed and typed just means statically typed. JavaScript is definitely untyped in this category.
See also:
What to know before debating type systems
Does “untyped” also mean “dynamically typed” in the academic CS world?
strong/weak can be thought of in relation to how the compiler, if applicable, handles typing.
Weakly typed means the compiler, if applicable, doesn't enforce correct typing. Without implicit compiler interjection, the instruction will error during run-time.
"12345" * 1 === 12345 // string * number => number
Strongly typed means there is a compiler, and it wants you an explicit cast from string to integer.
(int) "12345" * 1 === 12345
In either case, some compiler's features can implicitly alter the instruction during compile-time to do conversions for you, if it can determine that is the right thing to do.
Thus far, JavaScript can be categorized as Not-Strongly-Typed. That either means it's weakly-typed or un-typed.
dynamic/static can be thought of in relation to how the language instructions manipulate types.
Dynamically typed means the value's type is enforced, but the variable simply represents any value of any type.
x = 12345; // number
x = "string"; // string
x = { key: "value" }; // object
y = 123 + x; // error or implicit conversion must take place.
Statically typed means the variable type is strongly enforced, and the value type is less-so enforced.
int x = 12345; // binds x to the type int
x = "string"; // too late, x is an integer - error
string y = 123; // error or implicit conversion must take place.
Thus far, JavaScript can be categorized as Not-Statically-Typed. Also, it appears to be Dynamically Typed, if typed at all. So we need to see what Typing means.
Typed means that the language distinguishes between different types such as string, number, boolean, object, array, null, undefined and so on. Also each operation is bound to specific types. So you cannot divide an integer by a string.
2 / "blah" // produces NaN
Untyped means the operation of dividing integer by string would result in treating the first four bytes of string as integer. This is because Untyped operations take place directly on bits, there are no types to observe. The outcome will be something quite unexpected:
2 / "blah" // will be treated as 2 / 1500275048
Since JavaScript behaves according to the definition of being Typed, it must be. And therefore it must be Dynamically Typed, and Weakly Typed.
If anybody claims JavaScript is Untyped, it is merely for academic theory, not for practical application.
JavaScript is weakly typed. It is most certainly not "untyped" but its weakly typed nature allows for a lot of flexibility in terms of implicit conversions.
Keep in mind that JavaScript is also dynamically typed. This method of typing allows what is know as "duck typing".
For comparison consider that JavaScript is not strongly typed nor is it statically typed. Sometimes understanding what something isn't can help you see better what it is.
To the author's point JavaScript is also classified as Dynamically typed. Wiki states that Dynamically typed languages are type checked at runtime instead of in a compiler while Weakly Typed refers to the ability to change type on the fly within your code. So yes it is both Dynamically typed AND Weakly typed.
The problem here that is confusing a lot of programmers is that definitions like this are not standardized somewhere. The term untyped programming language is ambiguous. Does that refer to a language that has no data types or a language that is a lambda calculus untyped variant?
JavaScript/ECMAScript has a type system and all of its functions' domains will accept any Reference specification type. So that means JavaScript has a single data type, in reality. That is a matter of implementation that is more important to the very advanced JavaScript programmers. The average JavaScript programmer only cares about the abstract language data types that have been specified by ECMAScript.
In the context of the everyday programmer, not the researcher or theoretical computer scientist, the term untyped is a misnomer because most people aren't doing lambda calculus. Thus the term confuses the masses and seems to declare that JavaScript does not have any data types which is simply not true. Anyone who has ever used typeof knows that JavaScript has its own language data types:
var test = "this is text";
typeof(test);
yields
"string"
ECMAScript defines the following eight language types: Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object.
A more accurate designation for JavaScript would be implicitly typed, dynamically typed, or weakly/loosely typed (or some combination thereof), in that JavaScript uses type coercion in some cases which makes the type implicit because you don't have to explicitly specify the type of your variables. It falls under weakly typed because, unlike some languages which distinguish between float and integer etc, it just uses one number type to encompass all numbers, and makes use of the type coercion mentioned previously[Section 9 of ECMAScript Spec], in strong contrast to a strongly-typed language which would have very specific data types (i.e. you would have to specify int or float).
The definitions of statically and dynamically-typed languages are not standardized, however neither was the size of a byte when computers were beginning to evolve. Static and dynamic typing most often refer to the presence of certain language features. One of which is type-checking at runtime, or what is called dynamic type-checking. If you've used JavaScript, you already know that it definitely waits until runtime to check types, which is why you get TypeError exceptions during execution of your code. Example here
I think the top-voted answer is confusing JavaScript functions' polymorphism with functions that will accept literally anything (as with untyped variants of Lambda Calculus) which is an Association Fallacy.
Remember that JavaScript allows you to ask what is the typeof(your_variable), and compare types: 5==="5" returns false.
Thus I don't think you can call it untyped.
It is dynamically and (estimated as) weakly typed.
You may want to know it uses Duck typing (see andrew's link) and offers OOP though Prototyping instead of classes and inheritance.
While it is typed (you can ask "typeof someVar" and learn its specific type, it's very weak.
Given:
var a = "5";
you might say that a is a string. However, if you then write:
var b = a + 10;
b is an int equal to 15, so a acted just like an int. Of course, you can then write:
var c = a + "Hello World";
and c will equal "5Hello World", so a is again acting like a string.
I'd argue JavaScript is strongly and dynamically typed.
But that depends on a bunch of terms which seem to to be loosely defined at best, so the above is true only if you accept the definitions below...
Strong / Weak
"Strong" typing prevents operations intended for one type of data from being executed on another type. For example, trying to write to an Nth element of an array, where the object is not an array. Strong typing is required for memory safety.
"Weak" is the opposite of strong.
Static / Dynamic
"Static" typing checks types before program execution (at compile/transpile time). This requires the type information to be encoded into the language's syntax.
"Dynamic" is the oposite of static.
JavaScript will not let you corrupt the memory (hence "strong") but does all the checking and type conversions/coercions at run-time (hence "dynamic").
I find it helpful to think of "strong vs weak" as being orthogonal to "static vs dynamic". There are languages that are strong and static (e.g. C# without unsafe context), strong and dynamic (most "scripting" languages seem to fall into that category), weak and static (C/C++).
Not sure what would be weak and dynamic... assembler, perhaps :)
another interesting example of loosely typed JS:
console.log(typeof(typeof(5)))
the result is string. why? because the initial typeof results in 'integer' which in itself is a string. I would assume in a strongly typed language this type of changing types would not be a thing. perhaps i am mistaken but that was the first instance where i started to understand how CRAZY JS can be lol

Categories