I am trying to create a prototype/class that inherits from the object that is returned by a specific function. But I dont know what that object's name is?
For the instance var xhr = XMLHttpRequest(); what object is returned by xhr.responseXML;? Is it XMLDocument? Or maybe XMLDOM?
Also if I create the object var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); and call xmlDoc.load("xmlFile.xml" ); will it return the same type of object as xhr.responseXML;?
I am trying to do the following:
function XMLHandler()
{
this.xmlFile = "defaultXML.xml";
}
// Make XMLHandler inherit from Javascript object
XMLHandler.prototype = new XMLDocument();
XMLHandler.prototype.constructor = XMLDocument;
You shouldn't include unrelated questions in the same post. To address your second question about declaring a function within a "class":
Your first syntax, declaring it within the constructor, will pointlessesly overwrite myClass.prototype.publicFunct to point to a newly created function every time the constructor is called. That is, you will be creating an extra copy of the function with each call to the constructor, with myClass.prototype.publicFunct always pointing to the most recently created copy - or undefined until the constructor has been called at least once. Don't do this.
Your second option is simply invalid syntax in JavaScript.
Your third syntax is prefered. This will add the function to the prototype once.
Remember: JavaScript doesn't have classes as such, though you can sort of simulate them if you think it is worth the bother.
I can tell by your recent questions that you are thinking like Java, which this is not.
First question:
responseXML is different for each browser. Firefox gives a nsIDOMDocument, IE gives an IXMLDOMDocument and Webkit browsers depend on the responseType setting but will probably be Document. Since you cannot predict what it will be stop trying to extend it. In most cases the type isn't made available by the browser's API so javascript cannot extend it anyway.
Moreover, since JavaScript's inheritance is not class based you are forced into doing this:
XMLHandler.prototype = new XMLDocument();
...which simply does not work for your purpose. Any instance of XMLHandler will be built on an unrelated, empty document and not the document returned by responseXML. You have to use a wrapper here.
Second Question:
Of your 3 methods the first is equivalent to the last but more wasteful because it repeatedly sets the same function to the same prototype. The second is nonsensical, the syntax is broken. These are your real options:
// Instance method, every instance is given a copy of the function upon "new"
function MyClass()
{
this.publicFunct = function()
{
alert("public function");
};
}
// Prototypal method, only one copy of the function shared by all instances
function MyClass()
{
}
MyClass.prototype.publicFunct = function()
{
alert("public function");
};
// Shorthand method, same as prototypal but handy for several members at once
// It prevents MyClass from being a descendent of another type
function MyClass()
{
}
MyClass.prototype = {
// A colon is only acceptable in object notation
publicFunct: function()
{
alert("public function");
}
};
I would go with a prototypal method for efficiency unless you need to selectively add functions to a class. Your use of "public function" (also "class") seems like another symptom of an OOP background, there aren't any private functions in JavaScript so "public" has no place, all member functions are public. If at some point you do need a private function you can fake the effect with a closure.
(function() {
// Assignments are mostly global
MyClass = function() {};
MyClass.prototype.publicFunct = function()
{
privateFunct();
};
// These statements affect local scope
var foo = 'bar';
function privateFunct()
{
alert("public function");
}
})(); // These extra brackets cause the contents to be executed immediately
Having said that it is rare to need private functions and all JavaScript is visible anyway so it's not secret really. The above could be thwarted like this:
thief = {};
MyClass.prototype.publicFunct.call(thief);
// privateFunct is called by publicFunct in the context of the thief
You might as well accept that functions are public. You can go a step further and give up on classes altogether. Objects are just objects that happen to have some functions and those functions can even be shared with completely different objects.
Related
Sometimes techniques like this is used to keep variable reference or create singleton. In this way we will call createVariable one time only.
What are the pros and cons of this approach?
function createVariable() {
// usually here may be some long asynchronous task
//
return true;
}
function useVariable() {
if(!useVariable.someVar) {
useVariable.someVar = createVariable();
}
// do something with useVariable.someVar
}
// we will call useVariable several times.
// The idea is to call createVariable
// one time only.
useVariable();
useVariable();
useVariable();
I am grateful to all ideas and recommendations. I don't want to create a singleton. Just want to keep variable reference on function level. Without
pollute the global scope.
What are the pros and cons of this approach?
The approach is okay, although I question the need for it as higher-level design question.
The implementation has a couple of issues:
If someVar contains a falsey value, you'll recreate it when you shouldn't. To check if you've previously created it, use if(!useVariable.hasOwnProperty("someVar")) { rather than if(!useVariable.someVar) {.
The falsey values are 0, "", NaN, undefined, null, and of course, false. (All other values are "truthy".)
Functions have some built-in properties, both their own (name, length) and ones they get from their prototypes (various methods, mostly). So if your variables have names like name, length, call, and so on, you'll mistakenly think you've created them when you haven't as createVariable will already have those properties with truthy values (in your createVariable case). You can work around that by adding a prefix of some kind, or using a separate object as a map (although objects inherit properties, too, so you'd still probably need a prefix), or if you were using ES2015+, you could use a Map.
You've said you only want to create the variable once and "not pollute the global scope" (which is a good thing to avoid). I do that by just wrapping my code in a scoping function:
(function() {
var someVar = createSomeVar();
// My other code here
})();
That keeps the global namespace untouched, and creates only a single copy of someVar without the need for any particular plumbing.
Here is how you would create a singleton (from http://www.dofactory.com/javascript/singleton-design-pattern):
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;
}
};
})();
then use it like this
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
//You can see here that they are indeed the same instance
alert("Same instance? " + (instance1 === instance2));
NOTE: this took five seconds to find via Google: http://dofactory.com/javascript/singleton-design-pattern
So this is a somewhat weird problem that may not be possible but I was wondering if it is possible to get a variable linkage of the function that created an instance from javascript.
for example, i'd like to be able to do something like this:
function MyObject(){
console.log(this) // traces out the instance
console.log(MyObject) // traces out the function
console.log(this.parentClass) //Would like this to trace out the function as well. (or a similar call like it)
}
var test = new MyObject();
Is this at all possible? Thanks!!
It's possible if the prototype objects on the functions haven't been replaced, or if the code replacing them keeps the linkage as it is by default.
The constructor property is (by default and convention) the property you're looking for:
var test = new MyObject();
console.log(test.constructor === MyObject); // "true"
Note all of the caveats above, though. For instance, this is perfectly valid (and not particularly atypical) code:
function MyObject() {
}
MyObject.prototype = {
foo: function() { /* ... */ },
bar: function() { /* ... */ }
};
This is a common pattern, although one I don't recommend. Instead of adding to the object referred to by the MyObject.prototype property (an object that was set up by the JavaScript engine when creating MyObject), that code is creating an entirely new object and assigning it to the prototype property, making it refer to the new object. If that has been done, then the constructor property has been broken, and you can't use it the way you want to use it.
The constructor property on the default prototype object on functions is a funny thing about JavaScript. It's defined quite clearly in the specification that it will be there (it's ยง13.2 if anyone wants to read up), but as far as I'm aware nothing in the JavaScript engine actually uses it. (It isn't, for instance, used for instanceof.)
The problem with functional inheritance is that if you want to create many instances then it will be slow because the functions have to be declared every time.
The problem with prototypal inheritance is that there is no way to truly have private variables.
Is it possible to mix these two together and get the best of both worlds? Here is my attempt using both prototypes and the singleton pattern combined:
var Animal = (function () {
var secret = "My Secret";
var _Animal = function (type) {
this.type = type;
}
_Animal.prototype = {
some_property: 123,
getSecret: function () {
return secret;
}
};
return _Animal;
}());
var cat = new Animal("cat");
cat.some_property; // 123
cat.type; // "cat"
cat.getSecret(); // "My Secret"
Is there any drawbacks of using this pattern? Security? Efficiency? Is there a similar pattern out there that already exists?
Your pattern is totally fine.
There are a few things that you'd want to keep in mind, here.
Primarily, the functions and variables which are created in the outermost closure will behave like private static methods/members in other languages (except in how they're actually called, syntactically).
If you use the prototype paradigm, creating private-static methods/members is impossible, of course.
You could further create public-static members/methods by appending them to your inner constructor, before returning it to the outer scope:
var Class = (function () {
var private_static = function () {},
public_static = function () {},
Class = function () {
var private_method = function () { private_static(); };
this.method = function () { private_method(); };
};
Class.static = public_static;
return Class;
}());
Class.static(); // calls `public_static`
var instance = new Class();
instance.method();
// calls instance's `private_method()`, which in turn calls the shared `private_static();`
Keep in mind that if you're intending to use "static" functions this way, that they have absolutely no access to the internal state of an instance, and as such, if you do use them, you'll need to pass them anything they require, and you'll have to collect the return statement (or modify object properties/array elements from inside).
Also, from inside of any instance, given the code above, public_static and Class.static(); are both totally valid ways of calling the public function, because it's not actually a static, but simply a function within a closure, which also happens to have been added as a property of another object which is also within the instance's scope-chain.
As an added bonus:
Even if malicious code DID start attacking your public static methods (Class.static) in hopes of hijacking your internals, any changes to the Class.static property would not affect the enclosed public_static function, so by calling the internal version, your instances would still be hack-safe as far as keeping people out of the private stuff...
If another module was depending on an instance, and that instance's public methods had been tampered with, and the other module just trusted everything it was given... ...well, shame on that module's creator -- but at least your stuff is secure.
Hooray for replicating the functionality of other languages, using little more than closure.
Is it possible to mix functional and prototypical inheritance together and get the best of both worlds?
Yes. And you should do it. Instead of initializing that as {}, you'd use Object.create to inherit from some proto object where all the non-priviliged methods are placed. However, inheriting from such a "class" won't be simple, and you soon end up with code that looks more like the pseudo-classical approach - even if using a factory.
My attempt using both prototypes and the singleton pattern combined. Is there a similar pattern out there that already exists?
OK, but that's something different from the above? Actually, this is known as the "Revealing Prototype Pattern", a combination of the Module Pattern and the Prototype Pattern.
Any drawbacks of using this pattern?
No, it's fine. Only for your example it is a bit unnecessary, and since your secret is kind of a static variable it doesn't make much sense to me accessing it from an instance method. Shorter:
function Animal(type) {
this.type = type;
}
Animal.prototype.some_property = 123;
Animal.getSecret = function() {
return "My Secret";
};
Please help me decide whether I should use a function's prototype object and the "new" keyword or completely stay away from constructor functions.
Situation:
Function called widget() that will be called 10-15 times to initialize each widget on the page. widget() contains quite a few internal methods.
Each time widget() is called, the function needs to return an object that acts as an API to operate on the widget.
Question
1) Do I put all the internal methods inside Widget() under its prototype property? It does not make sense but the main reason for this is to not re-instantiate the internal functions every time widget() is called.
But if I do put the internal functions in prototype, each instantiated w object (w = new Widget();) has access to internal private methods.
2) If I stay away from constructor functions and new keyword and structure my code as down below, how do I fix the performance concern of the internal functions getting re-instantiated every time widget() is called.
function widget()
{
var returnObj = {};
/* Add internal functions but this will be re-instantiated every time */
return returnObj;
}
You have a bit of a tradeoff here. As you seem to already understand, methods you put on the .prototype are publicly available, but that is the most efficient places to put methods as they are automatically added to all new copies of that object in a very efficient manner. When using .prototype for methods, there is only one copy of your methods and a reference to that single copy is automatically added to all new instantiations of that object.
But, javascript doesn't have private methods built-in and the only work-around for that involves not using the .prototype for them or for any methods that need to call the private methods.
This article by Doug Crockford is a pretty good description of how you can create privacy for either data or methods in any object.
In either case, I don't see any reason to avoid using the new keyword to create new objects. You can make either .prototype or private methods work with new.
But, if you want to achieve truly private methods, then you can't use .prototype for either the private methods or any methods that need to access them so you have to decide which is more important to you. There is no single correct answer because your need for privacy is situation-specific.
In my coding, I generally don't enforce privacy and I do use .prototype and new. I designate "non-public" methods on the prototype by starting their name with an underscore. This is a notational convention, not an access enforcement scheme.
In answer to your second question about avoiding the new operator and reinstantiating methods, I'd just ask why you're doing this? What are you gaining? I'm not aware of any downsides to using new. As best I understand your decision about whether to use .prototype vs. manually create/assign methods in your constructor should be about the need for private methods.
FYI, 15 objects is hardly going to create a significant difference in performance either way here. I would evaluate your need for true privacy and make your decision based on that. If you HAVE to enforce privacy, then go with the Crockford method for implementing private methods. If you don't HAVE to have true privacy, then use .prototype. I don't see a reason here to avoid using new in either case.
You can use a metaconstructor* pattern to get around this.
function defineCtor(metaCtor) {
var proto = new metaCtor();
var ctor = proto.hasOwnProperty('constructor') ?
proto.constructor : new Function();
return (ctor.prototype = proto).constructor = ctor;
}
Now you have a function that constructs constructors (or more accurately constructs prototypes and returns constructors).
var Widget = defineCtor(function() {
function doInternalStuff() {
// ...cant see me
}
// this function ends up on the prototype
this.getFoo = function() { return doInternalStuff(); };
});
// ...
var myWidget = new Widget();
Explanation
defineCtor takes a single anonymous function as a property. It invokes the function with new, creating an object. It assigns the object as the prototype property of a new constructor function (either an empty function, or the generated prototype object's own constructor property), and returns that function.
This provides a closure for your internal functions, addressing your question 1, and sets up the constructor/prototype pair for you, addressing question 2.
Comparison
Compare the defineCtor technique to the following two examples.
This example uses the prototype, and has problem 1: the internal stuff is not encapsulated.
function Widget(options) {
this.options = options;
}
Widget.prototype = {
getFoo: function() {
return doInternalStuff();
}
};
// How to encapsulate this?
function doInternalStuff() { /* ... */ }
This example sets up everything in a constructor, and has problem 2: each time it constructs an object, it instantiates new function objects for each property.
function Widget(options) {
this.options = options;
function doInternalStuff() { /* ... */ }
this.getFoo = function() {
return doInternalStuff();
};
}
This example uses the technique described above to provide encapsulation while still leveraging the prototype:
var Widget = defineCtor(function() {
// ^
// This function runs once, constructing the prototype.
// In here, `this` refers to the prototype.
// The real constructor.
this.constructor = function(options) {
// In function properties, `this` is an object instance
// with the outer `this` in its prototype chain.
this.options = options;
};
function doInternalStuff() { /* ... */ }
this.getFoo = function() { return doInternalStuff(); };
});
// ...
var myWidget = new Widget();
This approach has a few benefits, some more immediately obvious than others.
It provides encapsulation. You could do this by wrapping the first "comparison" example in an immediately invoked function, but this approach may be cleaner and more easily "enforced" in a team setting.
It's extensible. You can give your "metaconstructor" functions their own prototypes, with function properties like "extends", "mixin", etc. Then, inside the body of metaCtor, you can write things like this.extends(BaseWidget). The defineCtor API never needs to change for any of this to happen.
It "tricks" Google Closure Compiler, Eclipse, jsdoc, etc. into thinking you are defining the actual constructor function rather than a "meta function." This can be useful in certain situations (the code is "self-documented" in a way these tools understand).
* As far as I know, the word "metaconstructor" is completely made up.
Is this code idomatic, or should I just acess the properties directly?
self.isAlive = function() {
return self.alive;
}
It all depends on implementation.
If you feel the property is always going to be the value, accessing the property is adequate. If you feel like there's going to be some logic that determines returning a "properly formatted" value, I would use a method (or if the value could possibly be dynamic based on other factors, a method is a good idea).
To go a step further, other languages like C# have properties making it safe to expose values, but not necessarily alter them. JS doesn't have such a method of protecting it, so often get<Var> is used to expose the property, but in a read-only fashion.
It's all about how you would like the data, while also trying to anticipate what the worst-case scenario could be if you expose the property directly vs. through a method.
It seems that you are speaking of properties in the classical OOP sense, i.e., properties of classes. In the current version of Javascript, simulating this behavior is not completely clean. Consider the following example:
var Widget = function() {
var private = 'private';
}
'Widget' is a constructor function, and 'private' will be instantiated in the scope of just the constructor function. That means there is only one way to get access to 'private' from outside the constructor function scope:
var Widget = function() {
var private = 'private';
this.getPrivate = function() {
return private;
}
}
This will hide the private variable for each instance of Widget, but unfortunately, 'getPrivate' must now be added to each instance of Widget. You can see this occurring in the constructor function by the statement this.getPrivate = .... Every time you make an instance of Widget using var widget1 = new Widget(), that specific instance will have a new function, 'getPrivate', added to it.
The normal way to make reusable components in Javascript is to use its implementation of Prototypical Inheritance. You assign a prototype object to the constructor function that will have shared methods and properties across all instances of the component. I will provide an example below to explain, but there are caveats to prototypical inheritance that you should become aware of if you are doing object-oriented javascript. A great resource.
Here's an example of how this might come in to play for your example:
var Widget = function() {
this.alive = true;
}
Widget.prototype.isAlive = function() {
return this.alive;
}
var widget1 = new Widget();
widget1.isAlive(); // returns true
The problem here is that the property alive is being added to the object, and thus, it is publicly available, i.e., any user of your Widget can simply look through the DOM in their favorite variation of FireBug and see (as well as freely modify) this property.
Consider a variation where you attempt to hide alive to external users. Because alive is a property of Widget instances, you would want to include the code to hide it in the constructor, as shown below:
var Widget = function() {
var alive = true;
}
However, as stated at the beginning of this post, alive in this case is only exposed to the constructor function's scope; therefore, it would not be accessible to methods on the prototype. The reason for this is that each of those methods do not have the same scope as the constructor function, since Javascript only has function scope.
In conclusion, if you're trying to hide data in a reusable component, javascript does not provide a clean way to do it. If you don't mind having new memory allocated on each component instance for the same methods, then you can use my second code example in this post. However, if you prefer to have your methods allocated in memory only once, then you will need to expose properties on the object instance, e.g., this.alive = true.
That's subjective. Use of getters and setters is very discussed. Some people (like me) say you should always use getters and setters to follow the encapsulation principle, while others say that you shouldn't since your application would become unmaintainable.
This is good practice if you don't want outside js code to modify your property. If this is the desired effect you might consider assigning that property using var instead of making it a property of that object. That way your code within the object can modify it but it can only be accessed through your getter
var alive = false;
function isAlive(){ return alive;}
You can use:
function isAlive(){
return arguments.callee.alive;
}
isAlive.alive=true;
This appears to be ok still in strict mode.
Another way to accomplish this is
function isAlive(){
return isAlive.alive;
}
isAlive.alive=true;
But the problem is that someone can use the name as a string, or rename the function etc... and you can loose the status.