TL;DR
Javascript was not at first intended to be a general purpose programming language, Python was.
Longer Answer
Javascript was developed in 1995 to add small amounts of behavior to web pages that at the time were almost entirely static documents. Pages with no JS were common, pages with a couple of inline scripts < 20 lines were about it. As Eric Lippert, a user here who worked on the Microsoft implementation has said it was just there to "make the monkey dance when you move the mouse".
So until about 15-20 years ago Javascript worked pretty much the way your conversation partner said: what's that? You want encapsulation of object internals in your < 100 LoC JS? Why?
But then a funny thing happened, people started using it more and more, and for ever more ambitious purposes. Then Microsoft invented the XmlHttpRequest object (2001) that allowed pages to communicate with the server in the background, and the world was never the same. By about 2005 it was available in most major browsers, and we had apps like gmail to show just what was possible with it.
Well, once people started writing real programs with Javascript, it became clear pretty quickly oh wait, we do actually need proper language features like private properties, encapsulation of internals, etc.
So people added them. Either in an ad hoc fashion (e.g. using closures for encapsulation), or increasingly to the language itself. Javascript has arguably had feature parity with the things that your conversation partner mentioned about Python since about 2015 (note that's almost 10 years now). So that person's information about JS is quite a bit out of date.
But in terms of language design, the designer(s) of Javascript didn't include those features earlier on because why bother, but once it was clear those features were necessary they added them for the same reasons Python has them.
But I see stuff when I console.log!!!
Yeah, about that. You see, the behavior of the console here is explicitly implementation-defined in the standard. So console.log
is pure magic: it need not be bound by the semantics of Javascript and can and does sometimes expose internals like [[Call]]
or [[Construct]]
that are not actually exposed to the Javascript programmer at all. So don't be surprised if you see private properties or the entire prototype chain or even inaccessible internals when you console.log
an object.
Contrast this with the behavior of print
in the reference implementation of Python: it very clearly spells out that objects get run through the str
function which calls the object's __str__
magic method if present and delegates to repr
if one is not found.
However it's worth noting here that Python (as far as I know) does not actually have a formal standard, and the behavior of the CPython reference implementation is not binding on alternative implementations, although I've never used it I would not be at all surprised if e.g. Jython did something quite different.
repr
(or an object's__repr__
method) must be called by a Python REPL, and indeed there are Python REPLs such as Jupyter which even render some objects as interactive applets, not just the text result ofrepr
. So this is really a question about tooling and it has very little to do with the language design or philosophy. $\endgroup$print(someObject)
in Python andconsole.log(someObject)
in JS. Python just prints something like<className address>
by default, while JS shows the full object contents. The problem is that their analogy is wrong. "Plain" JS objects are more like Python dictionaries, which do display all the contents. $\endgroup$