| I have not claimed JS is the weirdest. But I have not claimed "Normally C++/PHP/Ruby/Python devs don't really encounter these notorious problems, for many years now" either. Eigenclass (singleton_class) explained in another thread. I have not encountered Pythons for/else [1] yet. Right, typeof null exposed by Microsoft IE 2 (?). Web is many times bigger now yet even such a small mistake is not fixed. I have issue + of being concatenator, I prefer string interpolation, separate operators. Implicit type conversion often does not make sense spoils a lot [] * 2
//0
foo = {}
bar = {}
foo[bar] = 1 // just throw please
Object.keys(foo)
//["[object Object]"]
> they could also silently fail as well.But they don't. If only these rules were defined as library. I am sure it would be ditched long ago. Actually this may be argument in favor of operator overloading in JavaScript, the way to fix it. > Foo being an instance of function is MUCH more honest class Foo
end
Foo.send(:initialize)
TypeError (already initialized class)
# wrong one
Foo.instance_method(:initialize).call
NoMethodError (undefined method `call' for #<UnboundMethod: Foo(BasicObject)#initialize()>)
# does not allow unbound
Foo.new
new constructs an object and calls initialize. Same in JavaScript function Foo () {
console.log(this)
}
new Foo
// Foo {}
Foo()
// Window
It kind of make sense — new creates an object of constructor.prototype and calls constructor. I can't see how it is MUCH more honest than if new creates an object of prototype and calls prototype.constructor. By that logic Object.create is not honest Object.create(Object.prototype) // expects [[Prototype]] not constructor
Object.create(null)
And even if it was foo = {}
bar = Object.create(foo)
bar.__proto__ === foo
//true
bar.__proto__.__proto__ === Object.prototype
//true
bar.__proto__.__proto__.__proto__ === null
//true
class Foo {}
class Bar extends Foo {}
bar = new Bar
bar.__proto__ === Bar.prototype
bar.__proto__.__proto__ === Foo.prototype
bar.__proto__.__proto__.__proto__ === Object.prototype
bar.__proto__.__proto__.__proto__.__proto__ === null
I don't need constructor except in new, otherwise I use it only to access prototype. Absence of languages adopting this approach confirms its usability issues.> This is even more true because you are looking at the primitive rather than the function object which contains the primitive. Could you please expand this part? "Primitive" has specific meaning in JavaScript. [1] https://book.pythontips.com/en/latest/for_-_else.html |
Also, `__proto__` is deprecated. If you're writing JS, you should be using `.getPrototypeOf()` instead.
> Could you please expand this part? "Primitive" has specific meaning in JavaScript.
JS is torn on the idea of whether something is primitive or an object. You see this (for example) in Typescript with the primitive number being different from the Number type which represents a number object. To get at the primitive, you must actually call `.valueOf()` which returns the primitive in question. Meanwhile, you can attach your own properties to the function object -- a fact exploited by many, many libraries including modern ones like React. You can also add your own `.valueOf()` to allow your code to better interact with JS operators, but I believe that to pretty much always be a bad practice.