Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why shouldn't it work that way??? It's silently doing type conversion for you - from an object to a string. That's desired behavior. Just as most languages presented with "foo"+12 would silently convert 12 to a string via the toString() method.

What way do you think it should work? :/

An example of more sane usage:

  >>> var myv={}
  >>> var foo={toString:function(){return "12"}}
  >>> myv[foo]=34
  34
  >>> myv[12]
  34
>> "Also, the existence of an "===" operator should be troubling. Many people writing JS don't even know it exists."

You can't fault a language because some people don't make the effort to learn it properly.



I'm a karma burning mood so I'll keep going :]

This is the main problem I have with it; it's a very dynamic language but in a totally dangerous way. It should hash based on an object's identity or something; as it stands, there's no way to do that in JS without bolting your own junk on top, as a result you can't do real object<->object associations in JS.

Python for example has well-defined and useful behavior when you shove something into a dict type as a key, for strings it will hash based on the string value, for some other things it will uses identity, etc., and you can overload it (which you can in JS too of course, as you showed.)


maybe the default toString() should be a unique ID, as it is in for example Java, but it's not really a big deal. How often do you need object A->object B associations like that? Far easier to just put a pointer in all the object As to point to object Bs, and then put the object A's in an object/array.

Your use case is not something I've ever needed to be honest, and if you need it, it's simple to build it out yourself. For example, in an object constructor, just replace the toString() to return a unique ID for that object. A line of code :/

It's only dangerous when you don't understand what is happening. Why didn't you research why your image example was confusing you? As I say, read the book.


How often do you need object A->object B associations like that? Far easier to just put a pointer in all the object As to point to object Bs

This gives us an equivalent mapping, but unfortunately it alters the original object by adding a property to it. This sucks for two reasons; one is that the names might clash with a property that something else has set on that object, so you end up creating terrible names to avoid collisisions like someObject._prviate_associatedOtherObject or something, and then you have to make sure to destroy it when appropriate. It gets more hairy if you need multiple relations between the same objects. The other problem is that when you enumerate an object, now that property will show up. Gross. Yes, I know about the boilerplate you use to make enumerations in JS safe; my argument is that JS sucks as a language, and the necessity of stuff like this contributes to it.

For example, in an object constructor, just replace the toString() to return a unique ID for that object. A line of code :/

The Cappuccino/Objective-J guys at 280North have to do something similar (grep for OBJECT_COUNT++ in the source to see what I mean) in order to add identity to Obj-J objects.. but what if you didn't instantiate the object yourself? And I think this is the case where you'd be most likely to want to perform a mapping on an opaque object.


Sorry I'm replying to my own comment here, I don't have to time to wait for the next exponential decay on the reply button showing up before I have to leave. I'm actually replying to axod's comment on this same level.

Well here's an example, I have an AJAX instant messenger app. Due to the protocol it talks on, multiple users may have the same name (a reasonable request, I think.) When a contact on a user's buddy list connects, the JS library in charge of talking to the server passes an opaque ChatUser object (or whatever) to any registered callbacks. So, I write a second set of JS stuff to manage the GUI, like the window for the buddy list, etc., and register it to receive the callbacks from the protocol manager. When I get a user that connects, for example, I should probably create an html span with that user's name and away status in the div that holds the buddy list.

Now, when a buddy changes his/her away state, the protocol manager will tell the registered callbacks that a ChatUser has changed status (or you can register for a callback on the ChatUser object itself, either works.) We need to change the status message in that user's span. But how do you find the span we need to modify? The ChatUser object is mostly opaque except for a few documented calls we can make on it (getName, getStatus, etc). Setting new properties on it is probably a bad idea, since we don't know what the original library is going to be doing with it.

In another language you can just associate the span's identity with the ChatUser through a map or dictionary. But you can't associate based on identity in JS, so you're left setting some crazy property on the ChatUser instance and hoping it doesn't collide or cause problems. We can't base it on the ChatUser's name, because what if there are multiple Joe Browns in the contact list?

It's a contrived example, but I hope it illustrates the importance of associations. There are multiple workarounds for this situation. But they aren't elegant, which is why I think JS sucks :]


  1. You would keep a pointer to the span, in each ChatUser object.
  2. You would have *some* unique ID passed from server->client
     to identify which user its talking about. A session ID say.
     this could be used to lookup the ChatUser object.
>> "It's a contrived example, but I hope it illustrates the importance of associations. There are multiple workarounds for this situation. But they aren't elegant, which is why I think JS sucks :]"

Nope, and I actually think your proposed method - mapping ChatUser->span is incredibly ugly and inelegant. Horrible design. A ChatUser object should know what UI elements it is in control of directly.


Why? The original library does not deal with GUI at all. The ChatUser object does not need to know what GUI HTML elements it's associated with. One component of a piece of software extending another should not have to tamper with the original; this is just bad design in general, not OO or any specific flavor.


Please read up on MVC before you write any more code, for the love of sanity.


Care to give a concrete example of when you need an obj->obj mapping? I'm struggling to think of one.


Just as most languages presented with "foo"+12 would silently convert 12 to a string via the toString() method.

Most? The minority I'd expect. Others do things like

    TypeError: unsupported operand type(s) for +: 'dict' and 'int'


Axod may have overreached by saying "most languages". However, you overreach as well by saying "the minority" (though at least you add the qualifier "I'd expect".)

What Axod perhaps should have said is "most languages that support automatic type coercion."

We could have a flamewar all day about whether or not type coercion is a good or bad thing. And, actually, tumult's whole complaint could be summed up as type coercion is bad, and I don't get that object literals are different from string literals.

Many languages with type coercion, where objects can be converted to a string via a toString method of some sort, behave the same as Javascript. At most, like php, they log a warning or notice of some sort.

Personally, I prefer type coercion to throwing errors, and I prefer loose types to static types. Apparently, tumult doesn't, to the point of whining about the programming language that is the lingua franca of the web. To each his own.


No, I'm sure it's the minority. I was just being polite. :-) "Today's" programming languages are a minority too. Just think of all the ones that came and went in the 60s, 70, and 80s. Most of those were ones that wouldn't let you do "foo" + 12 as the OP said, i.e. you couldn't apply the plus operator to a string and an integer and have the integer coerced to a string automatically. It's clearly the minority that would do that, and a small minority at that.

awk and perl handle "foo" + 12, but they coerce "foo" to an integer, which is 0, and then add 12.

(Note, C lets you do "foo" + 12 but it isn't coercing 12 to a string, instead it's adding 12 to the address of the string "foo", e.g. "0123456789abcdef"[nibble].)

It would be interesting to enumerate those that do treat "foo" + 12 as if it was written "foo" + "12".

Edit: add http://en.wikipedia.org/wiki/List_of_programming_languages




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: