Hacker News new | ask | show | jobs
by belandrew 4390 days ago
> Python is more dynamic than JavaScript, in that it has __getattr__, __setattr__, __getitem__, etc.

No, it's not. You can do equivalents to all of those in Javascript. Javascript objects are all mutable with a few exceptions. They are just maps of properties, very similar to Python's. Properties can be added or changed at runtime.

For example, setattr(obj, item, value) in python is basically just obj[item] = value in js.

4 comments

__getattr__ and friends allow to customize the getters and setters.

JavaScript is in the process of getting similar capabilities with Harmony proxies, but the spec has yet to be finalized: http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxie...

I'm slightly confused by your wording but I think the functionality you're referring to is already available via Object.defineProperty's "get" and "set" options: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Object.defineProperty allows to overload get/set for a single key at a time.

Harmony proxies catch everything, and really overload the getter/setter mechanism.

No, JavaScript does not have Python's __getattr__, and obj[name] is not a substitute for it.

obj[name] works if you have already either assigned a value for that name, it exists in the prototype chain, or you have defined a getter via Object.defineProperty(). It's truly no different than obj.name[1] - `name` has to already exist in some form.

Python's __getattr__ [2] takes the attribute name as an argument, so it can be used to implement property access for any name, even those not known ahead of time.

Ruby has something similar with method_missing, and even more with define_method and instance_eval. Dart has noSuchMethod.

These are possible to implement in compile-to-JS language, but tricky to make fast. Dart's static analysis looks for all names that could be called on objects with a noSuchMethod, tries to figure out the most specific class it can add them to, then adds stubs to the JS prototypes to redirect to noSuchMethod(). A compile-to-JS Ruby could implement define_method easily enough, but method_missing is would be impossible to do the way Dart does it due to the open classes: you could dynamically add method_missing and not have the stubs available. If you want full Ruby semantics you have to abstract away method calls, which will be slow. I'm guessing the same problem exists for Python, so I wonder the same thing as the grandparent post: did they implement __getattr__ fully?

[1] With the small difference in the names that are allowed. [2] https://docs.python.org/3/reference/datamodel.html#object.__...

PythonJS implements __getattr__. See these regression tests: https://github.com/PythonJS/PythonJS/blob/master/regtests/cl...

https://github.com/PythonJS/PythonJS/blob/master/regtests/cl...

__getattr__ and __getattribute__ are implemented in the special __get__ function defined in: https://github.com/PythonJS/PythonJS/blob/master/pythonjs/ru...

My JS knowledge isn't great. In python, I can do operator overloading such that `obj[item] = value` does something completely different than assignment. Is that possible with JavaScript?
You can set a custom getters and setters, but I wouldn't call it operator overloading. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

So...

    > var x = {}
    > Object.defineProperty(x, 'value', { get: function() { return 1 }, set: function() { console.log('set') } })
    > x.value
    1
    > x.value = 2
    set
    > x.value
    1
I think he meant that you can overload operators in python and not javascript... but yeah I agree with you. At the end of the day javascript is still just as, or more, dynamic than python.