javascript

JavaScript parseInt(array) Only Converts the First Element

Converting from one type to another frequently causes bugs or unexpected result if you’re not careful. For example, when converting a string to an integer, we use the following function:

1
var num = parseInt(string, radix);

Accidentally, I used an array of numeric strings in place of string for conversion.

As stated in MDN parseInt:

If string is not a string, then it is converted to one. Leading whitespace in the string is ignored.

The array is converted to string.

If the array has only one element, then there won’t be any problem:

1
2
3
4
[10].toString()
> '10'
parseInt('10', 10)
> 10

But when there are more than one element, only the first element will be parsed:

1
2
3
4
[10, 5].toString()
> '10,5'
parseInt('10,5', 10)
> 10

Therefore, you have to be very careful when processing query parameter like:

1
?year=2013&year=2012

In many cases, it will be converted to:

1
year: ['2013', '2012']

After running through parseInt, it will result in 2013, might not be what you are looking for.

Share JavaScript Code between Browser (front-end) and Node (back-end)

One of the benefits coding in JavaScript is the ability to share code between
browser (front-end) and Node (back-end) environments.

To share code between two different environment, first need to understand what
are specific to browser and what are specific to Node. Shared code should be
agnostic to both environments.

In browser environment, there is an obvious one: window object. In Node
environment, there are a few objects that are not globally defined in browser:
global, process, module, exports and more, see global objects. All
these variables work, but exports is preferred.

1
console.log('Hi ' + (typeof window !== 'undefined' ? 'browser!' : 'Node!'));

Once environment is identified, then it is just the matter of writing style,
either browser style or Node style.

For example, writing in Node style by passing the exports as the parameter:

1
2
3
4
5
(function (exports) {
var foo = exports.foo = {};
// Node style code goes here.
}(typeof exports === 'undefined' ? this : exports));

By using browser style, here is an example from the annotated source code of
Underscore:

1
2
3
4
5
6
7
8
9
10
11
// Export the Underscore object for Node.js, with backwards-compatibility
// for the old require() API. If we're in the browser, add _ as a global
// object via a string identifier, for Closure Compiler "advanced" mode.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}

To make it easier without concerning the backward compatibility:

1
2
3
4
5
6
7
8
9
10
11
(function () {
var foo = {};
if (typeof exports !== 'undefined') {
exports.foo = foo;
} else {
this.foo = foo;
}
// Browser style code goes here.
}).call(this);

this is the same as window object in the browser environment.

1
2
3
(function (window) {
// Browser style code goes here.
}(this));

One more thing, writing in CoffeeScript is even better, because the compiled
code is already wrapped in closure, fewer indentation is needed.

1
2
3
4
5
6
7
foo = {}
if exports isnt 'undefined'
exports.foo = foo
else
this.foo = foo
# Browser style code goes here.

Compile to JavaScript by CoffeeScript 1.6.3:

1
2
3
4
5
6
7
8
9
10
11
12
(function() {
var foo;
foo = {};
if (exports !== 'undefined') {
exports.foo = foo;
} else {
this.foo = foo;
}
}).call(this);

Everything will be encapsulated inside the foo object.

Repeat Character Serveral Times in JavaScript

In Markdown, a header can be written as:

1
2
Header
======

This is a Setext-style headers, which are ‘underlined’ using equal signs (for
first-level headers) and dashes (for second-level headers)
. In order to
generate those underlined equal signs, a simple loop could be used to repeat
the character = several times. By the way, it is not necessary to have exact
number of the equal signs as the header length, but it just looks better. But
there is another way:

1
Array(heading.length + 1).join('=')

It is using the JavaScript Array global object to construct an empty Array
with the specified array length. Clever indeed!