Reputation: 5134
I found following prototype constructor (I call it create1
) in "JavaScript: The Good Parts" book (page 22). Because author encourages against new
keyword I tried to replicate this function without that keyword (create2
). The obvious drawback is that it writes to 'protected' __proto__
property. But does it produce the same result? To my inspection yes, but I may be wrong. Why author choosed to use new
here?
Object.create1 = function(o) { var F = function(){}; F.prototype = o; return new F(); };
Object.create2 = function(o) { var n = {}; n.__proto__ = o; return n; };
var proto = { number: 15, print: function () { return "number is " + this.number; } };
var _1 = Object.create1(proto);
var _2 = Object.create2(proto);
Upvotes: 0
Views: 94
Reputation: 39360
When it comes to Douglas Crockford and his opinion of constructor functions I think you should carefully consider he is opinionated about the syntax. He doesn't like it and would come up with lots of patterns to avoid using it.
After the following presentation I would not put much weight on what he has to say about constructor functions:
http://www.youtube.com/watch?v=ya4UHuXNygM
At 51:30 he says "classical inheritance" is wrong because setting up prototype part of Child you have to create an instance of Parent. That's wrong, I agree but has nothing to do with the "classical" way because he corrects this in his "better" way by using Object.create. He could have used Object.create in the "classical" way to begin with and there'd be no need for the "better" way.
At 1:00;30 he claims Parent constructor code can't be re used in Child but I'm sure he knows about Parent.call(this.args);
or does he? To use args in this way it does require you set up your functions to pass and receive arguments in a certain way. More info about this here under "Passing (constructor) arguments"
He complains about JavaScript trying to copy classical inheritance of Java but then continues complaining that the JavaScript style of defining constructor functions and prototype outside the constructor function doesn't look good (does it not look enough like Java?). There are benefits of being able to define your object over multiple files instead of having to put everything in one class/function/file.
Maybe Crockford is trolling because he does ask a couple of times "are you still with me" while he continues to destroy the prototype part of JavaScript until he ends up at 1:01:10 where he comes up with a pattern that doesn't use prototype at all (even though he praises JavaScript for having prototype and it being a great thing multiple times before that in this and the videos before this one).
I agree with the following: http://blog.millermedeiros.com/a-case-against-private-variables-and-functions-in-javascript/
Using privates is not useful. You need to indicate to developers that they should not use certain members then having an underscore in front of the name should do the trick. Other developers (and you) could still manipulate them if you have to. It's a risky thing because these members can be gone or re named in any update but it does allow you to test everything and test easier (even Java developers complain about the use of private). So Crockford's arguments for using the pattern at 1:01:00 that you have privates is not a valid point in my opinion and not liking the syntax was never a valid point as it has no technical merit.
In the link earlier posted I tried to explain how constructor functions and prototype works. I think it's important to know this before deciding it's bad and come up with patterns to work around it. Constructor functions and prototype can be hard to understand and even harder when people try to tell you to not use it and that it's wrong/out dated. A lot of documentation is incomplete or wrong (as with the example in the Crockford video) I think you should understand what it is and how to use it correctly first as it's a big part of how JavaScript works.
Upvotes: 1
Reputation: 665574
Why author choosed to use new here?
Because it's absolutely necessary. One cannot create prototype chains without new
, when Object.create
is not available (and .__proto__
is non-standard).
Do not overvalue that he "encourages against new". The answer to Is JavaScript's "new" keyword considered harmful? is definitely No. There are instances where a pure Object.create
is cleaner, and often enough new
does confuse newbies, but once you know how it works you can - and should - use it. Whenever you need instance initialisation code, a constructor is completely fine.
Upvotes: 3