
Recently there have been a lot of articles about Javascript. As holivarny, telling about how
bad he is, or what he is
good , and useful telling about some strange features and chewing "why so", like
this one .
And I decided to make my own micro-contribution to this topic.
For one of the typical tasks of storing data in the form of "key - value", almost always Javascript developers use an object. Just because the object itself is exactly the way it is, is a hash table, where the field name is the key. But this has a flaw, which I found out by burning myself on it. I illustrate it with the following test:
let a = { 'myKey': 'myValue' } let key = 'constructor'; // comes from outside source let b = a[key] || 'defaultValue'; expect(b).to.be.equal('defaultValue'); // fails
And all the code I have ever worked with said that all those developers who wrote it, like I did not stumble upon this problem, and, accordingly, did not try to deal with it.
To tell the details of why it broke, does not make sense, what happened is completely obvious. The probability to stumble on this behavior is low, but nonetheless, as it turned out, non-zero. The first thing I wanted to do was find the library that solves it, provides a hash table interface. But, after searching, I found only libraries that are completely isolated from the use of the object, and honestly calculate the hash. Of course, they are applicable and even necessary if you need to use an object, rather than a string or number, as a key. But they also have the ensuing drawback - they impose some “overhead” on which not everyone can agree. After a brief trials, I came to the conclusion that you still need to write another bike.
')
The
hash-map library solves this problem by hiding all the underlying fields with empty values:
const result = {}; for (var prop of Object.getOwnPropertyNames(Object.prototype)) { result[prop] = undefined; } return result;
Ways of use can be found in the readme.
Yet another JS library
The article turned out to be short, and there is nothing much to tell about this micro problem. Therefore, I decided to mention about another library -
typescript-reexport-generator . In the process of developing typescript, I resorted to different ways to export and import code between files; I came to the conclusion that the following is the most convenient. All .ts files in the folder export the code as follows:
// file1 export function myFunction(){} // file2 export class myClass{}
Next, the folder contains the index.ts file with the following contents:
export * from './file1'; export * from './file2';
Now you can import it like this:
// import { myFunction } from './folder/file1'; import { myClass } from './folder/file2'; // import { myFunction, myClass } from './folder';
In addition, between the files of one folder, you can import it like this:
import { myClass } from '.'; export function myFunction(){
There is one more mini-win: navigation in VSCode (ctrl + mouse click) works best with this export. Navigation from use to implementation in 1 click. With the default export, navigation was carried out in two clicks, which was somewhat depressing, so I quite quickly completely refused this.
And in order not to write these re-exports with my hands, I wrote a simple generator that creates these index.ts files from the task with gulp.watch. If you use the same import-export method, the library may be useful.
The lack of a library, and where without them, is that VSCode does not monitor file changes, therefore, the newly created file with exports does not immediately allow importing from outside. We have to enter the index with our hands so that the studio “sees” that a new line has appeared there. Another drawback that already depends on me is that gulp.watch does not tell what exactly has changed, so the generator has to view (and parse) all the files in the project. In the future, we may create the next version of the library where this will be decided. Only the first pass will be complete, and then only those files that have been modified will be parsed.