Is it possible to restrict inheritance in javascript ? I searched internet about restricting of inheritance in javascript but didn't find any useful information.Can someone explain on this topic of inheritance restriction ? I would like to restrict inheriting properties of my singleton object in other objects.
You cannot restrict inheritance in javascript. If you have a public constructor function that initializes an object, any other object can use it to make a derived object.
You can make many instance variables or even methods private with certain methods of declaration (see here for reference) which can reduce the usefulness or capabilities of a derived object though still doesn't prevent it.
Perhaps if you explain what problem you're really trying to solve, we could offer more concrete ideas on how to solve it.
OK, now that you've explained that you just want a singleton, then I'd suggest you use a singleton design pattern like this:
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
The constructor is private (contained within the closure) so it can't be called by other code and the means of getting the object is a function that only ever returns the single instance. Of course, any properties/methods on an object in JS can be copied, but a singleton like this can keep instance data in the closure if it wants where it cannot be copied.
References:
Learning Javascript Design Patterns - The Singleton Pattern
Singleton Design Pattern
Javascript Singleton Design pattern
Javascript Design Patterns: Singleton
Related
Can someone clarify the difference between a constructor function and a factory function in Javascript.
When to use one instead of the other?
The basic difference is that a constructor function is used with the new keyword (which causes JavaScript to automatically create a new object, set this within the function to that object, and return the object):
var objFromConstructor = new ConstructorFunction();
A factory function is called like a "regular" function:
var objFromFactory = factoryFunction();
But for it to be considered a "factory" it would need to return a new instance of some object: you wouldn't call it a "factory" function if it just returned a boolean or something. This does not happen automatically like with new, but it does allow more flexibility for some cases.
In a really simple example the functions referenced above might look something like this:
function ConstructorFunction() {
this.someProp1 = "1";
this.someProp2 = "2";
}
ConstructorFunction.prototype.someMethod = function() { /* whatever */ };
function factoryFunction() {
var obj = {
someProp1 : "1",
someProp2 : "2",
someMethod: function() { /* whatever */ }
};
// other code to manipulate obj in some way here
return obj;
}
Of course you can make factory functions much more complicated than that simple example.
One advantage to factory functions is when the object to be returned could be of several different types depending on some parameter.
Benefits of using constructors
Most books teach you to use constructors and new
this refers to the new object
Some people like the way var myFoo = new Foo(); reads.
Drawbacks
Details of instantiation get leaked into the calling API (via the new requirement), so all callers are tightly coupled to the constructor implementation. If you ever need the additional flexibility of the factory, you'll have to refactor all callers (admittedly the exceptional case, rather than the rule).
Forgetting new is such a common bug, you should strongly consider adding a boilerplate check to ensure that the constructor is called correctly ( if (!(this instanceof Foo)) { return new Foo() } ). EDIT: Since ES6 (ES2015) you can't forget new with a class constructor, or the constructor will throw an error.
If you do the instanceof check, it leaves ambiguity as to whether or not new is required. In my opinion, it shouldn't be. You've effectively short circuited the new requirement, which means you could erase drawback #1. But then you've just got a factory function in all but name, with additional boilerplate, a capital letter, and less flexible this context.
Constructors break the Open / Closed Principle
But my main concern is that it violates the open/closed principle. You start out exporting a constructor, users start using the constructor, then down the road you realize you need the flexibility of a factory, instead (for instance, to switch the implementation to use object pools, or to instantiate across execution contexts, or to have more inheritance flexibility using prototypal OO).
You're stuck, though. You can't make the change without breaking all the code that calls your constructor with new. You can't switch to using object pools for performance gains, for instance.
Also, using constructors gives you a deceptive instanceof that doesn't work across execution contexts, and doesn't work if your constructor prototype gets swapped out. It will also fail if you start out returning this from your constructor, and then switch to exporting an arbitrary object, which you'd have to do to enable factory-like behavior in your constructor.
Benefits of using factories
Less code - no boilerplate required.
You can return any arbitrary object, and use any arbitrary prototype - giving you more flexibility to create various types of objects which implement the same API. For example, a media player that can create instances of both HTML5 and flash players, or an event library which can emit DOM events or web socket events. Factories can also instantiate objects across execution contexts, take advantage of object pools, and allow for more flexible prototypal inheritance models.
You'd never have a need to convert from a factory to a constructor, so refactoring will never be an issue.
No ambiguity about using new. Don't. (It will make this behave badly, see next point).
this behaves as it normally would - so you can use it to access the parent object (for example, inside player.create(), this refers to player, just like any other method invocation would. call and apply also reassign this, as expected. If you store prototypes on the parent object, that can be a great way to dynamically swap out functionality, and enable very flexible polymorphism for your object instantiation.
No ambiguity about whether or not to capitalize. Don't. Lint tools will complain, and then you'll be tempted to try to use new, and then you'll undo the benefit described above.
Some people like the way var myFoo = foo(); or var myFoo = foo.create(); reads.
Drawbacks
new doesn't behave as expected (see above). Solution: don't use it.
this doesn't refer to the new object (instead, if the constructor is invoked with dot notation or square bracket notation, e.g. foo.bar() - this refers to foo - just like every other JavaScript method -- see benefits).
A constructor returns an instance of the class you call it on. A factory function can return anything. You would use a factory function when you need to return arbitrary values or when a class has a large setup process.
A Constructor function example
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("Jack");
new creates an object prototyped on User.prototype and calls User with the created object as its this value.
new treats an argument expression for its operand as optional:
let user = new User;
would cause new to call User with no arguments.
new returns the object it created, unless the constructor returns an object value, which is returned instead. This is an edge case which for the most part can be ignored.
Pros and Cons
Objects created by constructor functions inherit properties from the constructor's prototype property, and return true using the instanceOf operator on the constructor function.
The above behaviors can fail if you dynamically change the value of the constructor's prototype property after having already used the constructor. Doing so is rare, and it can't be changed if the constructor were created using the class keyword.
Constructor functions can be extended using the extends keyword.
Constructor functions can't return null as an error value. Since it's not an object data type, it is ignored by new.
A Factory function example
function User(name, age) {
return {
name,
age,
}
};
let user = User("Tom", 23);
Here the factory function is called without new. The function is entirely responsible for the direct or indirect use if its arguments and the type of object it returns. In this example it returns a simple [Object object] with some properties set from arguments.
Pros and Cons
Easily hides the implementation complexities of object creation from the caller. This is particularly useful for native code functions in a browser.
The factory function need not always return objects of the same type, and could even return null as an error indicator.
In simple cases, factory functions can be simple in structure and meaning.
Objects returned do not generally inherit from the factory function's prototype property, and return false from instanceOf factoryFunction.
The factory function can't be safely extended using the extends keyword because extended objects would inherit from the factory functions prototype property instead of from the prototype property of the constructor used by the factory function.
Factories are "always" better. When using object orientated languages then
decide on the contract (the methods and what they will do)
Create interfaces that expose those methods (in javascript you don't have interfaces so you need to come up with some way of checking the implementation)
Create a factory that returns an implementation of each interface required.
The implementations (the actual objects created with new) are not exposed to the factory user/consumer. This means that the factory developer can expand and create new implementations as long as he/she doesn't break the contract...and it allows for the factory consumer to just benefit from the new API without having to change their code...if they used new and a "new" implementation comes along then they have to go and change every line which uses "new" to use the "new" implementation...with the factory their code doesn't change...
Factories - better than all anything else - the spring framework is completely built around this idea.
Factories are a layer of abstraction, and like all abstractions they have a.cost in complexity. When encountering a factory based API figuring out what the factory is for a given API can be challenging for the API consumer. With constructors discoverability is trivial.
When deciding between ctors and factories you need to decide if the complexity is justified by the benefit.
Worth noting that Javascript constructors can be arbitrary factories by returning something other than this or undefined. So in js you can get the best of both worlds - discoverable API and object pooling/caching.
I think the factory function is superior to the constructor function. Using new with the constructor function, we are binding our code to one specific way of creating an object, while with a factory, we are free so we can create more different instances without binding ourselves. Let's say we have this class:
const file = new CreateFile(name)
If we want to refactor CreateFile class, creating subclasses for the file format our server supports, we can write an elegan factory function:
function CreateFile(name) {
if (name.match(/\.pdf$/)) {
return new FilePdf(name);
} else if (name.match(/\.txt$/)) {
return new FileTxt(name);
} else if (name.match(/\.md$/)) {
return new FileMd(name);
} else {
throw new Error("Not supprted file type");
}
}
with factory functions, we can implement private variables, hide the information from the users which is called encapsulation.
function createPerson(name) {
const privateInfo = {};
// we create person object
const person = {
setName(name) {
if (!name) {
throw new Error("A person must have a name");
}
privateInfo.name = name;
},
getName() {
return privateInfo.name;
},
};
person.setName(name);
return person;
}
For the differences, Eric Elliott clarified very well,
But for the second question:
When to use one instead of the other?
If you are coming from the object-oriented background, Constructor function looks more natural to you.
this way you shouldn't forget to use new keyword.
I often use the pattern of a main JavaScript constructor function and adding methods to its prototype object so they can be called intuitively by the user, for example:
function Slideshow(options) {
this.options = options
this.slideshow = $('#slideshow')
//more variables here
}
Slideshow.method1 = function () {
this.slideshow.addClass('test') // do something with slideshow variable
};
Slideshow.method2 = function () {
// another method
};
The one thing that really bugs me about this pattern is how in order to make variables accessible across all prototype methods, I have to add "this" in front of each variable inside the constructor function. It's a major pain, and I can't help but think there's a more elegant way to do this.
If I forgo using the prototype object and just add the methods as instance methods, I know I can't get around this problem, but I like the efficiency? and self encapsulating nature of this pattern. Any other suggestions for a better pattern? Thanks!
It's a major pain
No, it's really not. Every single JavaScript developer uses this syntax. If you were in Ruby or Python, you'd use self., in PHP you'd use $this->. Some languages like C++ don't require any special decorator, but JavaScript does.
and I can't help but think there's a more elegant way to do this.
No, there isn't.
This is JavaScript's syntax, you cannot change it, and you cannot work around it. If you want to access a property of this, you need this. before the property name. Otherwise, you're talking about global variables.
If you want a different syntax, consider a different language like CoffeeScript, which compiles to JavaScript.
meager has pretty much summed things up if you're talking about accessing public instance properties or methods. You have to use this in front of it as that's just how the language works.
But, if you have private instance properties or methods, you can define those as local variables inside the constructor and you can access them without this.
function slideshow(options) {
// no need to resave the options arguments as they can be used
// directly from the argument variable
// define a per-instance private variable that other methods defined
// within the constructor can use directly without the use of `this`
var theShow = $(options.selector || '#slideshow');
// define public methods
this.method1 = function() {
// can access private instance variable here without this in front of it
theShow.addClass('test');
}
this.method2 = function() {
theShow.addClass(options.decoaration);
}
}
This general design pattern is described here: http://javascript.crockford.com/private.html
Practically speaking, this works because the constructor function with the public methods declared inside it creates a closure that lasts for the duration of the object lifetime so the local variables in the constructor become per-instance variables accessible only from the functions declared within the constructor.
This question already has answers here:
Defining methods via prototype vs using this in the constructor - really a performance difference?
(7 answers)
Closed 8 years ago.
I know it's possible to mimic private variables in JS:
function ConstructorPattern() {
var privateVar = 'hi there';
this.getVar = function() {
return privateVar;
};
};
But according to Learning JavaScript Design Patterns when referring to some similar code with class Car and method toString:
The above is a simple version of the constructor pattern but it does suffer from some problems. One is that it makes inheritance difficult and the other is that functions such as toString() are redefined for each of the new objects created using the Car constructor. This isn't very optimal as the function should ideally be shared between all of the instances of the Car type.
So the solution given in my case would be to add the getVar function via the prototype:
ConstructorPattern.prototype.getVar = function() {
return privateVar;
};
But of course that function has no idea what privateVar is so it doesn't work. I am aware of the module pattern but I specifically want to be able to instantiate multiple instances.
Is there any way to use the constructor pattern "properly" with prototypes while still getting "private" functionality?
EDIT: If there isn't a way to accomplish this, is it really that bad for methods to be redefined for each class instance? I've recently started working on a code base that takes this approach. It seems like the only thing I'm missing out on is inheritance?
EDIT2: Marking as a duplicate based on link from the accepted answer.
Is there any way to use the constructor pattern "properly" with prototypes while still getting "private" functionality?
No. This pattern with privileged functions is based on closure scope, and cannot work with shared functions. All privileged methods must be instance-specific.
If there isn't a way to accomplish this, is it really that bad for methods to be redefined for each class instance?
No. Modern JavaScript engines optimize this pattern very well. Sure, there's a little overhead but you won't notice in typical setups.
It seems like the only thing I'm missing out on is inheritance?
Inheritance is still possible, see Define Private field Members and Inheritance in JAVASCRIPT module pattern. Sure, derived subclasses cannot directly access private variables that are declared in a parent constructor, but usually they don't need to anyway.
When you're creating getVar on the object's prototype, it wont be called when you do something like:
objectName.getVar();
Because the prototype's methods come AFTER object methods. An example below will show you what i mean:
function Car() {
var privy = "hidden";
this.getPrivy = function() {
return privy;
}
}
Car.prototype = {};
Car.prototype.getPrivy = function() {
return 'i came from prototype';
}
var obj = new Car;
obj.getPrivy();
JS follows a call chain such as:
Object method -> prototype method -> prototype prototype method etc.... all the way back to Object.prototype. It stops and returns when a valid method is found. In your case, your instance's method comes BEFORE your prototype's method.
I have been re-factoring someone else's JavaScript code.
BEFORE:
function SomeObj(flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version="1.1 (prototype)";
if (!this._someProperty) this._init();
// leading underscore hints at what should be a 'private' to me
this.reset(); // assumes reset has been added...
}
SomeObj.prototype.reset = function() {
/* perform some actions */
}
/* UPDATE */
SomeObj.prototype.getPrivate = function() {
return _private; // will return undefined
}
/* ...several other functions appended via `prototype`...*/
AFTER:
var SomeObj = function (flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version = "2.0 (constructor)";
this.reset = function () {
/* perform some actions */
};
/* UPDATE */
this.getPrivate = function() {
return _private; // will return true
}
/* other functions and function calls here */
}
For me the first example looks difficult to read, especially in a larger context. Adding methods like reset on like this, using the prototype property, seems much less controlled as it can presumably happen anywhere in the script. My refactored code (the second example above) looks much neater to me and is therefore easier to read because it's self-contained. I've gained some privacy with the variable declarations but I've lost the possibilities the prototype chain.
...
QUESTIONS:
Firstly, I'm interested to know what else I have lost by foregoing prototype, or if there are larger implications to the loss of the prototype chain. This article is 6 years old but claims that using the prototype property is much more efficient on a large scale than closure patterns.
Both the examples above would still be instantiated by a new operator; they are both 'classical'-ish constructors. Eventually I'd even like to move away from this into a model where all the properties and functions are declared as vars and I have one method which I expose that's capable of returning an object opening up all the properties and methods I need, which have privileges (by virtue of closure) to those that are private. Something like this:
var SomeObj = (function () {
/* all the stuff mentioned above, declared as 'private' `var`s */
/* UPDATE */
var getPrivate = function () {
return private;
}
var expose = function (flag) {
// just returns `flag` for now
// but could expose other properties
return {
flag: flag || false, // flag from argument, or default value
getPrivate: getPrivate
}
};
return {
expose: expose
}
})(); // IIFE
// instead of having to write `var whatever = new SomeObj(true);` use...
var whatever = SomeObj.expose();
There are a few answers on StackOverflow addressing the 'prototype vs. closure' question (here and here, for example). But, as with the prototype property, I'm interested in what a move towards this and away from the new operator means for the efficiency of my code and for any loss of possibility (e.g. instanceof is lost). If I'm not going to be using prototypal inheritance anyway, do I actually lose anything in foregoing the new operator?
A looser question if I'm permitted, given that I'm asking for specifics above: if prototype and new really are the most efficient way to go, with more advantages (whatever you think they might be) than closure, are there any guidelines or design patterns for writing them in a neater fashion?
...
UPDATE:
Note that expose returns a new object each time, so this is where the instantiation happens. As I understand this, where that object refers to methods declared in the SomeObj closure, they are the same methods across all objects (unless overwritten). In the case of the flag variable (which I've now corrected), this can be inherited from the argument of expose, have a default value, or again refer back to a encapsulated pre-existing method or property. So there are instances of objects being produced and there is some inheritance (plus polymorphism?) going on here.
So to repeat question 2: If I'm not going to be using prototypal inheritance anyway, do I actually lose anything in foregoing the new operator?
Many thanks for answers so far, which have helped to clarify my question.
In my experience, the only thing you lose by not using .prototype is memory - each object ends up owning its own copy of the function objects defined therein.
If you only intend instantiating "small" numbers of objects this is not likely to be a big problem.
Regarding your specific questions:
The second comment on that linked article is highly relevant. The author's benchmark is wrong - it's testing the overhead of running a constructor that also declares four inner functions. It's not testing the subsequent performance of those functions.
Your "closure and expose" code sample is not OO, it's just a namespace with some enclosed private variables. Since it doesn't use new it's no use if you ever hope to instantiate objects from it.
I can't answer this - "it depends" is as good an answer as you can get for this.
Answers:
You already answer this question: you loose the prototype chain. (Actually you don't loose it, but your prototype will be always empty). The consequences are:
There is a little performance/memory impact, because methods are created for each instance . But it depends a lot on the JavaScript engine, and you should worry about it only if you need to create a big amount of objects.
You can't monkey patch instances by modifying the prototype. Not a big issue either, since doing that leads to a maintenance nightmare.
Let me do a small pedantic correction to your question: Is not a matter of "prototype vs closure", in fact the concept of closure is orthogonal to a prototype based language.
The question is related on how you are going to create objects: define an new object from zero each time, or clone it from a prototype.
The example that you show about using functions to limit the scope, is a usual practice in JavaScript, and you can continue doing that even if you decide to use prototypes. For example:
var SomeObj = (function (flag) {
/* all the stuff mentioned above, declared as 'private' `var`s */
var MyObj = function() {}
MyObj.prototype = {
flag: flag,
reset: reset
};
return {
expose: function() { return new MyObj(); }
}
})();
If you are worried about modularization, take a look into requirejs which is an implementation of a technique called AMD (async module definition). Some people doesn't like AMD and some people love it. My experience with it was positive: it helped me a lot to create a modular JavaScript app for the browser.
There are some libraries to make your life with prototypes easier: composejs, dejavu, and my own barman (yes is a shameless self promotion, but you can look into the source code to see ways of dealing with definitions of objects).
About patterns: Since you can easily hide object instantiation using factory methods, you can still use new to clone a prototype internally.
What else I have lost by foregoing prototype?
I'm sure someone can provide an answer, but I'll at least give it a shot. There are at least two reasons to use prototype:
prototype methods can be used statically
They are created only once
Creating a method as an object member means that it is created for every instance of the object. That's more memory per object, and it slows down object creation (hence your efficiency). People tend to say that prototype methods are like class methods whereas member methods are like object methods, but this is very misleading since methods in the prototype chain can still use the object instance.
You can define the prototype as an object itself, so you may like the syntax better (but it's not all that different):
SomeObj.prototype = {
method1: function () {},
method2: function () {}
}
Your argument that it seems less controlled is valid to me. I get that it is weird to have two blocks involved in creating an object. However, it's a bit spurious in that there is nothing stopping someone from overwriting the prototype of your other object anyway.
//Your code
var SomeObj = function (flag) { //...
//Sneaky person's code
delete SomeObj.reset;
SomeObj.prototype.reset = function () { /* what now? */ }
Foregoing new
If you're only going to be creating specific object instances on the fly via {} notation, it's not really different from using new anyway. You would need to use new to create multiple instances of the same object from a class (function) definition. This is not unusual as it applies to any object oriented programming language, and it has to do with reuse.
For your current application, this may work great. However, if you came up with some awesome plugin that was reusable across contexts, it could get annoying to have to rewrite it a lot. I think that you are looking for something like require.js, which allows you to define "modules" that you can import with the require function. You define a module within a define function closure, so you get to keep the constructor and prototype definitions wrapped together anyway, and no one else can touch them until they've imported that module.
Advantages of closure vs. prototype
They are not mutually exclusive:
var attachTo = {};
;(function (attachTo, window, document, undefined) {
Plugin = function () { /* constructor */ };
Plugin.prototype = { /* prototype methods */ };
attachTo.plugin = Plugin;
})(attachTo, window, document);
var plugin = new (attachTo.plugin);
http://jsfiddle.net/ExplosionPIlls/HPjV7/1/
Question by question:
Basically, having the reset method in the prototype means that all instances of your constructor will share the exact same copy of the method. By creating a local method inside the constructor, you'll have one copy of the method per instance, which will consume more memory (this may become a problem if you have a lot of instances). Other than that, both versions are identical; changing function SomeObj to var SomeObj = function only differs on how SomeObj is hoisted on its parent scope. You said you "gained some privacy with the variable declarations", but I didn't see any private variables there...
With the IIFE approach you mentioned, you'll lose the ability to check if instance instanceof SomeObj.
Not sure if this answers your question, but there is also Object.create, where you can still set the prototype, but get rid of the new keyword. You lose the ability to have constructors, though.
I'm learning Javascript and have several questions concerning Javascript and OOP. I've noticed different declarations of functions in "classes" in various tutorials. First is the inside constructor:
Class = function () {
this.doSomething = function() {....};
}
And the other one is:
Class = function () {}
Class.prototype.doSomething = function() {....};
In which situations should the first construction be used, and in which situation should the second construction be used?
And the other question is: have I understood correctly that there's no protected properties or methods in js? What is to be used instead?
Thank you in advance!
When you define a function inside the constructor as this.myFunction=..., it is specific to your instance. This means that it must be constructed and kept in memory for all instances, which may be heavy. It also can't be inherited .
The only valid reason to do this are :
the enclosing of specific values
other types of specific functions (you might build a different function each time)
Most often, what you really need is a function defined on the prototype.
From the MDN on objects :
All objects in JavaScript are descended from Object; all objects
inherit methods and properties from Object.prototype, although they
may be overridden. For example, other constructors' prototypes
override the constructor property and provide their own toString
methods. Changes to the Object prototype object are propagated to all
objects unless the properties and methods subject to those changes are
overridden further along the prototype chain.
Regarding your additional question : the following code builds a non directly accessible function :
Class = function () {
var imprivate = function(){...};
this.doSomething = function() { uses imprivate};
}
A downside is that you have a different function instance for each instance of Class. This is most often done for modules (from which you have only one instance). Personally, I prefer to do exactly as suggested by ThiefMaster in comment : I prefix my private functions with _ :
// private method
XBasedGrapher.prototype._ensureInit = function() {