The difference of these approaches is that in the first case the inheritance mechanisms in js are activated, and in the second case, duck typing mechanisms are used.
When using the second method, the instanceof operator will not work - but then it can be "inherited" from the function, which cannot normally be done with prototypes.
But both methods are not ideal - in each of them a separate method is created for each object instance. When an (erroneous) attempt to apply such a method to a "foreign" instance of an object through call or apply , strange things are possible that will not be immediately apparent.
Therefore, the most modern way to create private fields is through symbols. In short: a call to Symbol("...") will give you some object that can be used as a field name, while calling the Symbol function again will give a new object. That is, if you “hide” a symbol, then the field will be private.
Here is an example, here the symbol is “hidden” using the “module” pattern:
var Constructor; !function() { var sName = Symbol("name") Constructor = function Constructor() { } Constructor.prototype[sName] = "foo" Constructor.prototype.get_name = function() { return this[sName]; } }() var foo = new Constructor();
The variable sName not visible outside the module - and therefore there is no access to the private name field from the outside, although it is quite easy to access it from inside the module.
The characters at the time of writing this answer are supported, unfortunately, only by Chrome and Ognelis from the main browsers. But for other browsers (IE) you can use a polyfill:
!function() { if (typeof window.Symbol === "function") return; var counter = 0; window.Symbol = function (name) { return "__" + name + "@" + ++counter; } }()
Such a symbol will not have most of the properties of the "real" symbols - but to create almost-private variables, it is fine.