Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.
In this article, we’ll look at some solutions to common JavaScript problems.
Prevent Text Selection After Double Click
We can stop text selection after a double click by calling preventDefault()
to stop the default action.
For example, we can write:
document.addEventListener('mousedown', (event) => {
if (event.detail > 1) {
event.preventDefault();
// ...
}
}, false);
Why is it Necessary to Set the Prototype Constructor?
We’ve to set the prototype constructor so that we can check with instanceof
that the prototype’s constructor is a given constructor.
For instance, if we have:
function Person(name) {
this.name = name;
}
function Student(name) {
Person.call(this, name);
}
Student.prototype = Object.create(Person.prototype);
Then the Student
‘s prototype is set to Person
.
But we actually want to set it to Student
, even though it inherits from Person
.
Therefore, we need to write:
Student.prototype.constructor = Student;
Now if we create an instance of Student
, and check if it with instanceof
:
student instanceof Student
Then that would return true
.
If we use the class syntax, then we don’t have to do that anymore.
We just write:
class Student extends Person {
}
and everything else is handled for us.
Creating Web Workers without a Separate Javascript File
We can create a web worker without creating a separate JavaScript file using the javascript/worker
as the value of the type
attribute.
For instance, we can write:
<script id="worker" type="javascript/worker">
self.onmessage = (e) => {
self.postMessage('msg');
};
</script>
<script>
const `blob = new Blob([
document.querySelector('#worker').textContent
];`
const worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = (e) => {
console.log(e.data);
}
worker.postMessage("hello");
</script>
We get the worker as a blob by using get the script element and use the textContent
property on it.
Then we create the worker with the Worker
constructor with the blob.
Then we write our usual worker code in the worker and the script invoking the worker.
How to Trim a File Extension from a String
We can trim the file extension from a string, we can use replace
method.
For instance, we can write:
fileName.replace(/\.[^/.]+$/, "");
We get the last part of the string that’s after the dot with the regex pattern.
And we replace it with the empty string.
In Node apps, we can use the path
module.
To get the name, we can write:
const path = require('path');
const filename = 'foo.txt';
path.parse(filename).name;
path.parse
takes the file path. Then we get the name
property from it.
Why does parseInt Return NaN with Array.prototype.map?
parseInt
returns NaN
with array instance’s map
method because parseInt
takes arguments but the map
callback takes 3 arguments.
parseInt
takes the number as the first argument and the radix as the 2nd argument.
The map
callback takes the array entry as the first argument, index as the 2nd argument, and the array itself as the 3rd argument.
Therefore, if we use parseInt
directly as the callback, then the index will be passed in as the radix, which doesn’t make sense.
This is why we may get NaN
.
We get that if the radix isn’t a valid radix.
Therefore, instead of writing:
['1','2','3'].map(parseInt)
We write:
['1','2','3'].map(Number)
or:
['1','2','3'].map(num => parseInt(num, 10))
Omitting the Second Expression When Using the Ternary Operator
If we have the following ternary expressions:
x === 1 ? doSomething() : doSomethingElse();
but we don’t want to call doSomethingElse
when x === 1
is false
, then we can use the &&
operator instead.
For instance, we can write:
x === 1 && dosomething();
Then if x === 1
is true
, then doSomething
is called.
Clear Cache in Yarn
We can clear the cache in yarn by using the yarn cache clean
command.
innerText Works in IE, but not in Other Browsers
innerText
is an IE-only property for populate texting content of a node.
To do the same thing other browsers, we set the textContent
property.
For instance, we write:
const el = document.`getElementById`('foo');
el.textContent = 'foo';
Conclusion
We can stop selection after double-clicking by calling preventDefault
to stop the default action from running.
Also, we shouldn’t use parseInt
as a callback for map
.
We’ve to set the constructor to the current constructor if we create a child constructor.
This way, we can check for the instance properly.