4

I was once asked by a student why we write:

  • parseInt(something)
  • something.toLowerCase()

that is, why one has the variable as a parameter, while the other is applied to the variable.

I explained that while toLowerCase is a method of string objects, parseInt wasn’t designed that way. OK, so it’s window.parseInt, but that just makes it a method of a different object.

But it struck me as an inconsistency — why are some string or other functions not methods of their corresponding objects?

The question is why? Is there a technical reason why parseInt and other functions are not methods, or is that just a historical quirk?

10
  • parseInt is a "global" and is actually window.parseInt - does that help Commented Jan 21, 2017 at 10:16
  • @JaromandaX But why? I’ll edit the question to make it clearer. Commented Jan 21, 2017 at 10:20
  • 1
    @trincot toString also does type conversion, yet it’s not toString(something). atob and btoa also turn strings into strings, yet they aren’t used as something.atob() or something.btoa(). Commented Jan 21, 2017 at 10:24
  • 2
    Historical quirk, inconsistency, call whatever you want it. Javascript is full of weird quirks. Commented Jan 21, 2017 at 10:26
  • 2
    Parsing is typically done by a global object. See also JSON.parse(str), not str.parseAsJSON(). Same for btoa, encodeURI, .... Commented Jan 21, 2017 at 10:28

3 Answers 3

3

In general, Javascript was designed in a hurry, so questioning each individual design decision isn't always a productive use of your time.

Having said that, for parseInt in particular, the reason is simple to explain: it accepts pretty much any arbitrary type, like:

parseInt(undefined)  // NaN

Since you cannot implement undefined.parseInt(), the only way to do it is to implement it as a static function.

As of ECMAScript 2015, parseInt has been mirrored in Number.parseInt, where it arguably makes more sense than on window. For backwards compatibility window.parseInt continues to exist though.

Sign up to request clarification or add additional context in comments.

6 Comments

JavaScript may have been written in 10 days, but it’s been around for many years now, time to clean it up a little. I didn’t know that it’s been mirrored in the Number object, so that makes some sense. It also makes sense that it’s in the Number object to allow unknown incoming data. Do you know of any other functions which have had this treatment?
@Manngo: LOL. Backward compatibility usually kills most of the clean-up efforts. In any language. Python3 tried it, it was released 8 years ago, and python2 is still popular....
"the reason is simple to explain" - well, I'm not sure if that's the chicken or the egg. You pass in the argument in a language with crazy dynamic rules so it's natural to accept anything, even though it makes no sense at all. Why on earth would you like to parse anything else than a string as an integer? If you love the merits of static typing you feel deep inside this just asks for trouble...
@Karoly Well, without interviewing Brendan personally on the matter, we'll never find an answer. If you're on board with the crazy dynamic types at all, this parseInt implementation makes sense. For example, you can also use it to truncate floats… If you insist on the sanity of type safety, Javascript is the wrong language to get riled up about. ;)
@Manngo A bunch of methods on Number underwent this transformation. You can look through other global objects and see if you can spot other such methods.
|
2

In this specific case it makes sense with respect to encapsulation.

Consider parseInt() - it is taking a value of an unknown type from an unknown location and extracting an integer value from it. Which object are you going to have it a method of? All of them?

String.toUpperCase() should only take a string as input (else something which may be cast as a string) and will return a string. This is well encapsulated within a small subset of cases, and since values are not strongly typed it seems logical to not have it as a global function.

As for the rest of JavaScript I have no idea nor do I have insight into the real reason it was done this way, but for these specific examples it appears to me to be a reasonable design decision.

Comments

0

The development progress of the JavaScript language is quite fast in recent years. With that in mind, a lot of things are still in the API due to backward compatibility - historical reasons as you said. Although I can't say that's the only reason.

In JavaScript, you can approach a problem not just with Object oriented paradigm (where methods of objects usually shares a common state). Another, functional approach can be applied quite easily without getting into too much trouble with JavaScript language.

JavaScript gives great power to its users with many possibilities of approaching a problem. There is a saying: "With Great Power Comes Great Responsibility".

2 Comments

I'm not sure what you mean by methods of objects usually share a common state, or why you refer to this as a "functional approach".
I slightly edited the answer to express it more clearly. I haven't meant to refer to that as a "functional approach", I referred to the "Object oriented" paradigm. In object oriented programming, objects hold a state which is usually mutated by object's methods.Functional world is conceptually different where we try to avoid side effects.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.