1

As we know, we use function and "new" to create objects in Javascript.

var Cat = function() {...};
var cat = new Cat();

However, from the perspective of programming language design, I think it is quite obscure to people's intuition. How do people come up with this design?

(The point is not about the "new" keyword, but syntactically using a "function" to create object, which is obscure. Object is just Object. Why does it have anything to do with a function?)

czheo
  • 1,771
  • 2
  • 12
  • 22
  • 1
    Maybe it came from languages like C++ and Java. Which it did. What languages are you familiar with? – Pointy Jul 11 '15 at 21:22
  • 1
    It was a design choice to make JavaScript be [Protoype-based](https://en.wikipedia.org/wiki/Prototype-based_programming). In any case it is defined in the [ECMAScript standard](https://es5.github.io/#x11.2.2) and works to establish the [Prototype] chain and implicitly creates a new object, etc. The [Prototype] can be established also with Object.created, but that's a different question.. – user2864740 Jul 11 '15 at 21:27
  • The linked duplicate isn't about JavaScript explicitly, but because JavaScript took the syntax directly from Java/C++ I think it's applicable. – Pointy Jul 11 '15 at 21:27
  • I am familiar with C, C++, Java, Python, Ruby, PHP and etc. All of them are class-based OOP which wrap a constructor in a Class. I don't consider this design such similar to C++ or Java. – czheo Jul 11 '15 at 21:29
  • @czheo The primary difference between JavaScript and other C-family languages is the prototypal inheritance scheme. There is no such thing as a "class" in JavaScript (even though ES2015 makes it seem like there is, sort-of). – Pointy Jul 11 '15 at 21:33
  • 4
    Also, questions like "why did the designers of Language X do Y" are not really great Stackoverflow questions. – Pointy Jul 11 '15 at 21:34
  • @Pointy Other prototype based OOP such as Io is never using function to create objects. Object is just Object. Why it has anything to do with a function? – czheo Jul 11 '15 at 21:40
  • @Pointy And this question is not duplicated with what you pointed out. – czheo Jul 11 '15 at 21:46
  • 2
    @czheo you're not going to like this - but the design came from a very uninspiring place - looking familiar to Java developers. I can dig out a reference if you'd like one or you can search yourself for interviews with Brendan Eich where he clarifies it. In its entirety, the `new` feature was designed to please people coming from c++ and Java. – Benjamin Gruenbaum Jul 11 '15 at 21:50
  • 1
    It was not a "well thought out" choice to dualize functions as constructors, it was a mistake caused by a language being designed in 10 days by someone who has never done it before. In retrospect functions would have worked like in ES6 where a `class` can't be invoked without a constructor and an arrow functions can't be invoked as a constructor - it's just an historical mistake. – Benjamin Gruenbaum Jul 11 '15 at 21:51
  • @BenjaminGruenbaum Thx for your reasonable answer. Makes sense to me. I'd also like to see the reference. – czheo Jul 11 '15 at 21:56
  • 1
    @BenjaminGruenbaum That - it "is not well thought out" - is a personal conjecture. There are a few wards in JavaScript, but the "dualiza[tion of] functions" or the lack of classes or 'class' as such is not one that I would claim as such. Even ES6 classes don't change the fundamentals of the model and - IMOHO - will be even more confusing to those who thinking that JavaScript OO is (or should be like) that in another language. – user2864740 Jul 11 '15 at 22:02
  • 1
    @user2864740 agreed - JavaScript "classes" are much, much different from classes in languages like C++, C#, Java, Python, Ruby, etc. There really isn't any such thing as a "class". What there is in JavaScript is the effects of prototype inheritance. It's really a totally different concept. – Pointy Jul 11 '15 at 22:07
  • I totally understand what class based and prototype based model differ from each other. But absence of classes in JS doesn't make excuse for using a FUNCTION to create Objects. – czheo Jul 11 '15 at 22:10
  • @czheo `new` creates the object, not the function. In many years of practice I've run into *no issues* with this "not well thought out" approach of having a[ny] function be able to act as a constructor-function. It is very powerful to be able to create and return *new* constructor-functions and it fits uniformly in the function-as-first-class-citizen model; also once the function-constructor is created it (being just a value) often hides being a monikor ('Cat') variable anyway. – user2864740 Jul 11 '15 at 22:26
  • @user2864740 To be exact, the return value of "new any_function()" is a object. People are complaining about this design out there. http://ericleads.com/2012/09/stop-using-constructor-functions-in-javascript/ – czheo Jul 11 '15 at 22:28
  • 2
    @czheo To be correct, `new` *creates* the object and then invokes the function with the *already/newly created object* as the function's context (aka 'this'). The prototype chain (and a few other details) have already been established when the constructor-function runs. That article argues for `Object.create`, which is fine (and *is actually closer to the Prototype model*) but it has nothing to do with 'classes'. Also, broken code is broken code: if someone "forgets" `new` then they already messed up. Not JavaScript's fault; might as well have used `*` instead of `+`. – user2864740 Jul 11 '15 at 22:30
  • 1
    @czheo Wrt the result of `new`: If a constructor-function invoked with new does not return an object then it is equivalent to returning `this` (the object created by `new` impliitly); if it does explicitly return a[n different] object then that object is the result of the `new` expression. – user2864740 Jul 11 '15 at 22:35
  • @user2864740 This answer seems making more sense to me. `new` to create the the object, and then invoke the function with its context. This explain agrees with the syntax. Thx! – czheo Jul 11 '15 at 22:38
  • @user2864740 sure, it's an opinion, but not mine - I'm merely saying what the people who _invented_ the language think about the design choices. Of course once a language is out their say isn׳t everything. – Benjamin Gruenbaum Jul 12 '15 at 04:55
  • @BenjaminGruenbaum If there is a specific article or interview or blog with Mr. Eich I would very much like to read it. I've not actively looked for such myself (and the whole prop 8 debacle hides a good bit of actually useful results). – user2864740 Jul 12 '15 at 05:28

2 Answers2

-1

Initialising an instance can involve logic, so using a function is a natural choice.
Specific syntax could have been invented for this, but in the end a constructor is a block of code, optionally with some parameters: just like a function.

P Varga
  • 19,174
  • 12
  • 70
  • 108
-1

Several years later, I somehow convinced myself. It is not obscure to create an object using function. Actually, a function that creates an object is called "constructor", which should've been obvious enough to me when I look back now but unfortunately wasn't at the time when I asked this question.

After you define the Cat constructor as the function like below,

var Cat = function() {
  this.legs = 4;
}

when you invoke new Cat(), JS somewhat adds 2 lines implicitly behind the scene.

var Cat = function() {
  this = {}; // implicitly added
  this.legs = 4;
  return this; // implicitly added
}
czheo
  • 1,771
  • 2
  • 12
  • 22