I was wondering how accessing to strings is done. The String object exposes methods such as char(Code)At for public access, but doesn't use them itself as part of its other methods, for example indexOf, but instead accesses the string through an internal structure. However, when using a RegExp, I assume it can't use String's private properties, so it has to call the public API as any other class. I wrote a short test to see that, but it doesn't seem that's what happens: https://jsfiddle.net/n5pxe94L/
String.prototype[Symbol.iterator]=function*()
{
console.log("My custom iterator!");
yield "t";
};
const originalFunc=String.prototype.charCodeAt;
String.prototype.charCodeAt=function(index)
{
console.log("Used!");
return originalFunc.call(this,index);
}
new RegExp("a").test("Lalalala");
When I run this test, it doesn't print anything, which indicates the functions I overrode aren't used! So how does RegExp access the string it analyzes?
It's all done in the JavaScript engine however that engine sees fit to do it. Each JavaScript implementation may take a different approach, but they all have direct, very low-level access to the string's content. For performance reasons I'd expect these access methods to be highly optimized and direct, not allowing for overrides like you've attempted here as that would slow things down in the 99.9999% of cases where no such override exists.
JavaScript is not stuck using functions exposed in the API, it may have many others that are hidden from developers and for internal use only.
If you're writing JavaScript code you're stuck using the features available to you. If you're writing a JavaScript runtime you can do whatever you want.
Originally I wanted to simply answer along the lines of RegExp accesses the underlying string structure in C but I got curious so started digging into the source code of various javascript engines.
All the javascript engines commonly in use (which are V8 for Chrome and node.js, Chakra for Edge and JavascriptCore for Safari) implement regexp processing in C++. I couldn't find the exact regexp processing functions in Chakra and JavascriptCore but I'm sure if I spend a few days reading the code I'll find it.
For Chakra you will see that most of the Regexp methods in C++ accept an argument called input which is defined as Char*. I'm not sure if input is the string or the regexp pattern but I'm guessing it's the string. But note that it is Char not char so it is probably a custom class in the project. You can start by looking at the Chakra RegexpRuntime implementation here: https://github.com/microsoft/ChakraCore/blob/master/lib/Parser/RegexRuntime.cpp
For JavascriptCore best I can tell is that they pass the C++ JSString object to the regexp function. This is as close as to actually using the actual String prototype in js but it probably has methods not available to js: https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/runtime/RegExpObject.cpp
I got the furthest with V8 in the last 15 minutes. V8 passes a parameter called subject as the string to regexp functions. This is a String object which is then converted to String::FlatContent. Now what is FlatContent? It is an array-like object (see the Vector class) of either 8 bit or 16 bit values that you can access using the [] operator in C++. This allows them to loop through the string using regular array indexing. You can start by checking out regexp.cc: https://github.com/v8/v8/blob/master/src/regexp/regexp.cc
As you can see, none of them access strings via Javascript's String object as is. The closest that works kind of how you expected them to behave is Apple's JavascriptCore in Safari but even then it's not using merely APIs exposed via javascript.
Related
Objects in JavaScript can be used as Hashtable
(the key must be String)
Is it perform well as Hashtable the data structure?
I mean , does it implemented as Hashtable behind the scene?
Update: (1) I changed HashMap to hashtable (2) I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?
Update 2 : I understand, I just wonder how V8 and the Firefox JS VM implements the Object.properties getters/setters?
V8 doesn't implement Object properties access as hashtable, it actually implement it in a better way (performance wise)
So how does it work? "V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes" - that make the access to properties almost as fast as accessing properties of C++ objects.
Why? because in fixed class each property can be found on a specific fixed offset location..
So in general accessing property of an object in V8 is faster than Hashtable..
I'm not sure how it works on other VMs
More info can be found here: https://v8.dev/blog/fast-properties
You can also read more regarding Hashtable in JS here:(my blog) http://simplenotions.wordpress.com/2011/07/05/javascript-hashtable/
"I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?"
I am no expert, but I can't think of any reason why a language spec would detail exactly how its features must be implemented internally. Such a constraint would have absolutely no purpose, since it does not impact the functioning of the language in any way other than performance.
In fact, this is absolutely correct, and is in fact the implementation-independence of the ECMA-262 spec is specifically described in section 8.6.2 of the spec:
"The descriptions in these tables indicate their behaviour for native
ECMAScript objects, unless stated otherwise in this document for particular kinds of native ECMAScript objects. Host objects may support these internal properties with any implementation-dependent behaviour as long as it is consistent with the specific host object restrictions stated in this document"
"Host objects may implement these internal methods in any manner unless specified otherwise;"
The word "hash" appears nowhere in the entire ECMA-262 specification.
(original, continued)
The implementations of JavaScript in, say, Internet Explorer 6.0 and Google Chrome's V8 have almost nothing in common, but (more or less) both conform to the same spec.
If you want to know how a specific JavaScript interpreter does something, you should research that engine specifically.
Hashtables are an efficient way to create cross references. They are not the only way. Some engines may optimize the storage for small sets (for which the overhead of a hashtable may be less efficient) for example.
At the end of the day, all you need to know is, they work. There may be faster ways to create lookup tables of large sets, using ajax, or even in memory. For example see the interesting discussion on this post from John Reseig's blog about using a trie data structure.
But that's neither here nor there. Your choice of whether to use this, or native JS objects, should not be driven by information about how JS implements objects. It should be driven only by performance comparison: how does each method scale. This is information you will get by doing performance tests, not by just knowing something about the JS engine implementation.
Most modern JS engines use pretty similar technique to speed up the object property access. The technique is based on so called hidden classes, or shapes. It's important to understand how this optimization works to write efficient JS code.
JS object looks like a dictionary, so why not use one to store the properties? Hash table has O(1) access complexity, it looks like a good solution. Actually, first JS engines have implemented objects this way. But in static typed languages, like C++ or Java a class instance property access is lightning fast. In such languages a class instance is just a segment of memory, end every property has its own constant offset, so to get the property value we just need to take the instance pointer and add the offset to it. In other words, in compile time an expression like this point.x is just replaced by its address in memory.
May be we can implement some similar technique in JS? But how? Let's look at a simple JS function:
function getX(point) {
return point.x;
}
How to get the point.x value? The first problem here is that we don't have a class (or shape) which describes the point. But we can calculate one, that is what modern JS engines do. Most of JS objects at runtime have a shape which is bound to the object. The shape describes properties of the object and where these properties values are stored. It's very similar to how a class definition describes the class in C++ or Java. It's a pretty big question, how the Shape of an object is calculated, I won't describe it here. I recommend this article which contains a great explanation of the shapes in general, and this post which explains how the things are implemented in V8. The most important thing you should know about the shapes is that all objects with the same properties which are added in the same order will have the same shape. There are few exceptions, for example if an object has a lot of properties which are frequently changed, or if you delete some of the object properties using delete operator, the object will be switched into dictionary mode and won't have a shape.
Now, let's imagine that the point object has an array of property values, and we have a shape attached to it, which describes where the x value in this property array is stored. But there is another problem - we can pass any object to the function, it's not even necessary that the object has the x property. This problem is solved by the technique called Inline caching. It's pretty simple, when getX() is executed the first time, it remembers the shape of the point and the result of the x lookup. When the function is called second time, it compares the shape of the point with the previous one. If the shape matches no lookup is required, we can take the previous lookup result.
The primary takeaway is that all objects which describe the same thing should have the same shape, i.e. they should have the same set of properties which are added in the same order. It also explains why it's better to always initialize object properties, even if they are undefined by default, here is a great explanation of the problem.
Relative resources:
JavaScript engine fundamentals: Shapes and Inline Caches and a YouTube video
A tour of V8: object representation
Fast properties in V8
JavaScript Engines Hidden Classes (and Why You Should Keep Them in Mind)
Should I put default values of attributes on the prototype to save space?
this article explains how they are implemented in V8, the engine used by Node.js and most versions of Google Chrome
https://v8.dev/blog/fast-properties
apparently the "tactic" can change over time, depending on the number of properties, going from an array of named values to a dictionary.
v8 also takes the type into account, a number or string will not be treated in the same way as an object (or function, a type of object)
if i understand this correctly a property access frequently, for example in a loop, will be cached.
v8 optimises code on the fly by observing what its actually doing, and how often
v8 will identify the objects with the same set of named properties, added in the same order (like a class constructor would do, or a repetitive bit of JSON, and handle them in the same way.
see the article for more details, then apply at google for a job :)
Objects in JavaScript can be used as Hashtable
(the key must be String)
Is it perform well as Hashtable the data structure?
I mean , does it implemented as Hashtable behind the scene?
Update: (1) I changed HashMap to hashtable (2) I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?
Update 2 : I understand, I just wonder how V8 and the Firefox JS VM implements the Object.properties getters/setters?
V8 doesn't implement Object properties access as hashtable, it actually implement it in a better way (performance wise)
So how does it work? "V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes" - that make the access to properties almost as fast as accessing properties of C++ objects.
Why? because in fixed class each property can be found on a specific fixed offset location..
So in general accessing property of an object in V8 is faster than Hashtable..
I'm not sure how it works on other VMs
More info can be found here: https://v8.dev/blog/fast-properties
You can also read more regarding Hashtable in JS here:(my blog) http://simplenotions.wordpress.com/2011/07/05/javascript-hashtable/
"I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?"
I am no expert, but I can't think of any reason why a language spec would detail exactly how its features must be implemented internally. Such a constraint would have absolutely no purpose, since it does not impact the functioning of the language in any way other than performance.
In fact, this is absolutely correct, and is in fact the implementation-independence of the ECMA-262 spec is specifically described in section 8.6.2 of the spec:
"The descriptions in these tables indicate their behaviour for native
ECMAScript objects, unless stated otherwise in this document for particular kinds of native ECMAScript objects. Host objects may support these internal properties with any implementation-dependent behaviour as long as it is consistent with the specific host object restrictions stated in this document"
"Host objects may implement these internal methods in any manner unless specified otherwise;"
The word "hash" appears nowhere in the entire ECMA-262 specification.
(original, continued)
The implementations of JavaScript in, say, Internet Explorer 6.0 and Google Chrome's V8 have almost nothing in common, but (more or less) both conform to the same spec.
If you want to know how a specific JavaScript interpreter does something, you should research that engine specifically.
Hashtables are an efficient way to create cross references. They are not the only way. Some engines may optimize the storage for small sets (for which the overhead of a hashtable may be less efficient) for example.
At the end of the day, all you need to know is, they work. There may be faster ways to create lookup tables of large sets, using ajax, or even in memory. For example see the interesting discussion on this post from John Reseig's blog about using a trie data structure.
But that's neither here nor there. Your choice of whether to use this, or native JS objects, should not be driven by information about how JS implements objects. It should be driven only by performance comparison: how does each method scale. This is information you will get by doing performance tests, not by just knowing something about the JS engine implementation.
Most modern JS engines use pretty similar technique to speed up the object property access. The technique is based on so called hidden classes, or shapes. It's important to understand how this optimization works to write efficient JS code.
JS object looks like a dictionary, so why not use one to store the properties? Hash table has O(1) access complexity, it looks like a good solution. Actually, first JS engines have implemented objects this way. But in static typed languages, like C++ or Java a class instance property access is lightning fast. In such languages a class instance is just a segment of memory, end every property has its own constant offset, so to get the property value we just need to take the instance pointer and add the offset to it. In other words, in compile time an expression like this point.x is just replaced by its address in memory.
May be we can implement some similar technique in JS? But how? Let's look at a simple JS function:
function getX(point) {
return point.x;
}
How to get the point.x value? The first problem here is that we don't have a class (or shape) which describes the point. But we can calculate one, that is what modern JS engines do. Most of JS objects at runtime have a shape which is bound to the object. The shape describes properties of the object and where these properties values are stored. It's very similar to how a class definition describes the class in C++ or Java. It's a pretty big question, how the Shape of an object is calculated, I won't describe it here. I recommend this article which contains a great explanation of the shapes in general, and this post which explains how the things are implemented in V8. The most important thing you should know about the shapes is that all objects with the same properties which are added in the same order will have the same shape. There are few exceptions, for example if an object has a lot of properties which are frequently changed, or if you delete some of the object properties using delete operator, the object will be switched into dictionary mode and won't have a shape.
Now, let's imagine that the point object has an array of property values, and we have a shape attached to it, which describes where the x value in this property array is stored. But there is another problem - we can pass any object to the function, it's not even necessary that the object has the x property. This problem is solved by the technique called Inline caching. It's pretty simple, when getX() is executed the first time, it remembers the shape of the point and the result of the x lookup. When the function is called second time, it compares the shape of the point with the previous one. If the shape matches no lookup is required, we can take the previous lookup result.
The primary takeaway is that all objects which describe the same thing should have the same shape, i.e. they should have the same set of properties which are added in the same order. It also explains why it's better to always initialize object properties, even if they are undefined by default, here is a great explanation of the problem.
Relative resources:
JavaScript engine fundamentals: Shapes and Inline Caches and a YouTube video
A tour of V8: object representation
Fast properties in V8
JavaScript Engines Hidden Classes (and Why You Should Keep Them in Mind)
Should I put default values of attributes on the prototype to save space?
this article explains how they are implemented in V8, the engine used by Node.js and most versions of Google Chrome
https://v8.dev/blog/fast-properties
apparently the "tactic" can change over time, depending on the number of properties, going from an array of named values to a dictionary.
v8 also takes the type into account, a number or string will not be treated in the same way as an object (or function, a type of object)
if i understand this correctly a property access frequently, for example in a loop, will be cached.
v8 optimises code on the fly by observing what its actually doing, and how often
v8 will identify the objects with the same set of named properties, added in the same order (like a class constructor would do, or a repetitive bit of JSON, and handle them in the same way.
see the article for more details, then apply at google for a job :)
I know we can do this via DWR library to work with Java objects in Javascript.
But I would like to know if we can actually instantiate Java Objects in Javascript, using plain Javascript objects?
I searched on the internet and found this link and this link which speaks about Packages object in Javascript. I even read that this object is a part of JS since JS 1.1, is that true?
But when I actually used var myClass = new Packages.myPackage.myClass(); , it says, Packages is not defined, obviously I am missing out something here.
For my use case I have to instantiate a Java Pojo in JS.
Any clue folks on how to achieve this?
This feature depends on the JavaScript engine (i.e. the interpreter which runs the JavaScript). I haven't tried to do this in a browser but it might be possible when the Java plugin is enabled (which you shouldn't do for security reasons, at least not unconditionally).
The special object Packages is a feature of the Rhino engine, for example, which is a JavaScript interpreter that runs in a Java VM. The Packages has overloaded the accessor methods so when you write Packages.com.pany.Foo, it will internally look up the class and return something that wired the Java and the JavaScript worlds in a useful way.
You can find a tutorial here: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/Scripting_Java
You can create a Java object and assign it to a variable in JavaScript with the help of the new
keyword. When you create an instance of a Java class, JavaScript automatically creates a JavaObject
object. For example, you can instantiate a Java String from JavaScript and assign it to a variable.
Then you can use the dot operator to access the object’s length()
var myString=new java.lang.String("Test String");
alert(myString.length()); //prints 11
You can follow this link for more information http://www.sitepoint.com/connect-java-to-javascript-with-liveconnect/
Many programmers say it is a bad practice to use the eval() function:
When is JavaScript's eval() not evil?
I'd like to take a moment to address the premise of your question - that eval() is "evil"...
Is this eval() dangerous?
Buggy evaled code can violate security properties just as easily as buggy source code...
Why not eval() JSON?
There are a number of ways that your security may be compromised...
Is there ever a good reason to use eval()?
Yes - when there is no other way to accomplish the given task with a reasonable level of clarity... This eliminates 99% of cases where eval is used...
Why is eval unsafe in javascript?
The danger of eval only rears its ugly head when you are serving a script written by alice to user bob for bob's browser to eval...
So why does it exist in the first place?
Because sometimes there is a need. All the same reasons for/against using eval in JavaScript can likely be shared with the use of reflection in Java, for example.
However, I agree with everything you quoted in your question. Many reasons for using it are ill-advised, and best done differently - but sometimes, there is still a need, or it is simply the "best choice" over other available alternatives. (I'd focus on the answers to Is there ever a good reason to use eval()? for additional reasons.)
+1 to your question for good research.
eval() exists because sometimes you want to give complete programmatic control of your application to code passed in at run time.
Languages without an eval() feature can definitely provide (a subset? all?) of this functionality by asking each programmer to essentially write their own eval() -- lex the input, parse the input, create new objects as necessary, run methods or functions on them via simple string comparisons or similar. In essence, duplicate the entire interpreter that already exists and is debugged and fast.
Eval is actually a powerful feature and there are some things that are impossible to do without it. For example:
Evaluate code received from a remote server. (Say you want to make a site that can be remotely controlled by sending JavaScript code to it?)
Evaluate user-written code. Without eval, you can't program, for example, an online editor/REPL.
Creating functions of arbitrary length dynamically (function.length is readonly, so the only way is using eval).
Loading a script and returning it's value. If your script is, for example, a self-calling function, and you want to evaluate it and get it's result (eg: my_result = get_script_result("foo.js")), the only way of programming the function get_script_result is by using eval inside it.
Re-creating a function in a different closure.
And anything else you'd want to do that involves creating code on the fly.
The reason it is considered "evil" is because it's classicaly used by novices to do things that the language can handle natively. For example, the code below:
age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");
And the code below:
age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);
Both do the same thing, except one parses a string, generates code from it, compiles into machine code and then runs, while the other reads a value from a hash, which is a lot faster.
There's a research publication exacty on this topic:
The Eval That Men Do -- A Large-scale Study of the Use of Eval in JavaScript Applications
Mirror on Wayback Machine
It is to me the most comprehensive answer to this question to date.
Quote from the abstract:
We have recorded the behavior of 337 MB of strings given as
arguments to 550,358 calls to the eval function exercised in over
10,000 web sites.
Amongst other, they identified 9 categories of recurring eval:
JSON - A JSON string or variant.
JSONP - A padded JSON string.
Library -One or more function definitions.
Read - Read access to an
object’s property.
Assign - Assignment to a local variable or
object property.
Typeof - Type test expression.
Try - Trivial
try/catch block.
Call - Simple function/method call.
Empty -
Empty or blank string.
A snippet from the conclusion (which is too long to be quoted entierly):
[...] While many uses eval were legitimate, many were unnecessary and
could be replaced with equivalent and safer code. We started this work
with the hope that it would show that eval can be replaced by other
features. Unfortunately our data does not support this conclusion.[...]
A paper well worth reading.
The eval() feature is like scissors. You're an adult, it's your responsibility to not run with them.
I've seen the design philosophy of dynamic languages (like JavaScript) summarised as preferring to enable smart people to do clever things above trying to prevent stupid people from doing silly things. (Unfortunately I can't recall the original source or phrasing.)
If you're worried about introducing bugs with eval, you can use strict mode. It seems to prevent some of the problems with how the feature is designed. (That is, as a "magic" function allowed to clobber your namespace.)
Eval exists to simplify tasks in JavaScript. You can use it evaluate multiple statements. Instead of having to find another way you can use eval to do such things. Even though it is discouraged it has considerable power and use.
Objects in JavaScript can be used as Hashtable
(the key must be String)
Is it perform well as Hashtable the data structure?
I mean , does it implemented as Hashtable behind the scene?
Update: (1) I changed HashMap to hashtable (2) I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?
Update 2 : I understand, I just wonder how V8 and the Firefox JS VM implements the Object.properties getters/setters?
V8 doesn't implement Object properties access as hashtable, it actually implement it in a better way (performance wise)
So how does it work? "V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes" - that make the access to properties almost as fast as accessing properties of C++ objects.
Why? because in fixed class each property can be found on a specific fixed offset location..
So in general accessing property of an object in V8 is faster than Hashtable..
I'm not sure how it works on other VMs
More info can be found here: https://v8.dev/blog/fast-properties
You can also read more regarding Hashtable in JS here:(my blog) http://simplenotions.wordpress.com/2011/07/05/javascript-hashtable/
"I guess most of the browser implement it the same, if not why not? is there any requirement how to implement it in the ECMAScript specs?"
I am no expert, but I can't think of any reason why a language spec would detail exactly how its features must be implemented internally. Such a constraint would have absolutely no purpose, since it does not impact the functioning of the language in any way other than performance.
In fact, this is absolutely correct, and is in fact the implementation-independence of the ECMA-262 spec is specifically described in section 8.6.2 of the spec:
"The descriptions in these tables indicate their behaviour for native
ECMAScript objects, unless stated otherwise in this document for particular kinds of native ECMAScript objects. Host objects may support these internal properties with any implementation-dependent behaviour as long as it is consistent with the specific host object restrictions stated in this document"
"Host objects may implement these internal methods in any manner unless specified otherwise;"
The word "hash" appears nowhere in the entire ECMA-262 specification.
(original, continued)
The implementations of JavaScript in, say, Internet Explorer 6.0 and Google Chrome's V8 have almost nothing in common, but (more or less) both conform to the same spec.
If you want to know how a specific JavaScript interpreter does something, you should research that engine specifically.
Hashtables are an efficient way to create cross references. They are not the only way. Some engines may optimize the storage for small sets (for which the overhead of a hashtable may be less efficient) for example.
At the end of the day, all you need to know is, they work. There may be faster ways to create lookup tables of large sets, using ajax, or even in memory. For example see the interesting discussion on this post from John Reseig's blog about using a trie data structure.
But that's neither here nor there. Your choice of whether to use this, or native JS objects, should not be driven by information about how JS implements objects. It should be driven only by performance comparison: how does each method scale. This is information you will get by doing performance tests, not by just knowing something about the JS engine implementation.
Most modern JS engines use pretty similar technique to speed up the object property access. The technique is based on so called hidden classes, or shapes. It's important to understand how this optimization works to write efficient JS code.
JS object looks like a dictionary, so why not use one to store the properties? Hash table has O(1) access complexity, it looks like a good solution. Actually, first JS engines have implemented objects this way. But in static typed languages, like C++ or Java a class instance property access is lightning fast. In such languages a class instance is just a segment of memory, end every property has its own constant offset, so to get the property value we just need to take the instance pointer and add the offset to it. In other words, in compile time an expression like this point.x is just replaced by its address in memory.
May be we can implement some similar technique in JS? But how? Let's look at a simple JS function:
function getX(point) {
return point.x;
}
How to get the point.x value? The first problem here is that we don't have a class (or shape) which describes the point. But we can calculate one, that is what modern JS engines do. Most of JS objects at runtime have a shape which is bound to the object. The shape describes properties of the object and where these properties values are stored. It's very similar to how a class definition describes the class in C++ or Java. It's a pretty big question, how the Shape of an object is calculated, I won't describe it here. I recommend this article which contains a great explanation of the shapes in general, and this post which explains how the things are implemented in V8. The most important thing you should know about the shapes is that all objects with the same properties which are added in the same order will have the same shape. There are few exceptions, for example if an object has a lot of properties which are frequently changed, or if you delete some of the object properties using delete operator, the object will be switched into dictionary mode and won't have a shape.
Now, let's imagine that the point object has an array of property values, and we have a shape attached to it, which describes where the x value in this property array is stored. But there is another problem - we can pass any object to the function, it's not even necessary that the object has the x property. This problem is solved by the technique called Inline caching. It's pretty simple, when getX() is executed the first time, it remembers the shape of the point and the result of the x lookup. When the function is called second time, it compares the shape of the point with the previous one. If the shape matches no lookup is required, we can take the previous lookup result.
The primary takeaway is that all objects which describe the same thing should have the same shape, i.e. they should have the same set of properties which are added in the same order. It also explains why it's better to always initialize object properties, even if they are undefined by default, here is a great explanation of the problem.
Relative resources:
JavaScript engine fundamentals: Shapes and Inline Caches and a YouTube video
A tour of V8: object representation
Fast properties in V8
JavaScript Engines Hidden Classes (and Why You Should Keep Them in Mind)
Should I put default values of attributes on the prototype to save space?
this article explains how they are implemented in V8, the engine used by Node.js and most versions of Google Chrome
https://v8.dev/blog/fast-properties
apparently the "tactic" can change over time, depending on the number of properties, going from an array of named values to a dictionary.
v8 also takes the type into account, a number or string will not be treated in the same way as an object (or function, a type of object)
if i understand this correctly a property access frequently, for example in a loop, will be cached.
v8 optimises code on the fly by observing what its actually doing, and how often
v8 will identify the objects with the same set of named properties, added in the same order (like a class constructor would do, or a repetitive bit of JSON, and handle them in the same way.
see the article for more details, then apply at google for a job :)