4 ms·
What's wrong with JS's object model? It's certainly more flexible than say Java's. If the problem is the flexibility, do you feel the same way about Ruby?
by ehsanu1 15y ago
What's wrong with JS's object model? It's certainly more flexible than say Java's. If the problem is the flexibility, do you feel the same way about Ruby?
- MostAwesomeDude 15y agoImplicit coercion is always iffy, and JS's coercion rules are broken along the same lines as PHP's, where == and === have to be carefully managed. There's no actual identity check, only two different strengths of equality. Booleans coercing to strings instead of strings coercing to booleans is weird. There's no operator overloading. Sometimes this is useful, in languages which have it. Notably, there's no way to override how equality, coercion, and arithmetic are handled. There are no metaclass operations. The type model is incomplete; it's not possible to create new first-class types or query type information respecting inheritance. For that matter, there's no blessed way to have inheritance. Makes sense since the language doesn't have classes per se, but it's kinda annoying in an object-based language to not be able to actually examine objects in a unified way. Those are the ones off the top of my head. There are others, but they're matters of opinion.
- glyph 15y agoThere's plenty not to like about JavaScript, but the biggest mess is this: js> x = 1 1 js> z = x.y js> // WTF?? In other words: it's not an error to access an attribute of an object which isn't there. It's dicey enough that you can have attributes in Python and Ruby that can be misspelled, and mismatch their declarations, without an immediate compiler error. But, that is reasonable to deal with as long as you have pretty good unit test coverage: after all, if you run the code that is actually accessing the attribute, you'll quickly see that there's a run-time error and fix it: irb(main):001:0> x = 1 => 1 irb(main):002:0> z = x.y NoMethodError: undefined method `y' for 1:Fixnum from (irb):2 ~or~ >>> x = 1 >>> z = x.y Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'int' object has no attribute 'y' ... and you need unit test coverage anyway, because the compiler can't save you from a huge variety of other violations, so it's not like this is really making much extra work for you. In JavaScript, by the time you actually encounter an error, it's too late to figure out where the heck the erroneous object is getting generated. So, if you have some code like 'this.observers.push(object.somefunc);', every test case which adds an observer must also verify what happens when the observer gets called: and it has to be the same test so you have some idea where the observer came from, whereas you can easily make those things different tests in Python. Then, in order to get reasonable error-reporting behavior from quick things which aren't tested, you have to have tons of manual type-checks anywhere that objects are put into a persistent container, because by the time you have some random 'undefined' in your list of observers, it's far too late to figure out how it got there. This type of paranoid defensive programming is a bad idea in Python and Ruby, because you can just let the language runtime do its job and inform you if there's an error, and your stacktraces will give you a good idea where it is. The fact that sometimes unknown things are 'undefined' and sometimes they're 'null' and sometimes they're '"undefined"' and sometimes they're the empty string and sometimes they're 0 really compounds this problem. Python has None, Ruby has nil, and nobody uses random ad-hoc sentinel values because why would you do that? The thing that just blows my mind is that the designers of JavaScript must have _known_ that this was a terrible idea, because: js> undefined.undefined typein:1: TypeError: undefined has no properties js> null.nothing typein:2: TypeError: null has no properties so when you are two steps out from the misspelling that caused your error, you can figure out that something has in fact gone wrong. And: js> blub typein:3: ReferenceError: blub is not defined since the assumption that everything you really care about in JavaScript is going to be a global variable, and prototype attributes are kind of an afterthought. After all, why would you store data in organized structures when you can just stuff it all into an undifferentiated bag of crap in the global namespace! It's all going to go away when you reload the page, right? Except then Node comes along and changes the equation so you actually have to live with your persistent data structures and you probably want to know when things go wrong in your long-running servers. Oops. Here I really have to agree with Ted: despite the fact that there are advantages to be had from keeping your client and your server in the same language and leveraging your investment in utility libraries in both places, JavaScript really is bad enough language that it's worth the effort to use something different when you can.