Static methods in JavaScript - javascript

If I have a class declared in prototype.js
var ClassFoo = Class.create();
ClassFoo.prototype = {
initialize: function() {
},
type: 'ClassFoo'
};
If I declare a method ClassFoo.doBar = function() { log("foobar") }
Is it the same as/equivalent to creating a static method in java ?
Can an object of classfoo access doBar() ?

Yes, methods on the constructor are analogous to static methods in other OOP languages. They are available globally (or in whatever scope the constructor is defined in) and are not associated with any particular instance of that object (which is pretty much what a static method is).
Any code anywhere in your project can access them as ClassFoo.doBar(). Your methods of ClassFoo can access it that way too. There are no other shortcuts for accessing them (even from methods).
One thing to remember is that functions in Javascript are objects and can have properties just like any other object in Javascript. So, assigning:
ClassFoo.doBar = function() {...};
is just assigning a property to the ClassFoo object and it can be used like any property on any object.
ClassFoo.doBar();

Related

Better way to access variables across prototype methods in JavaScript?

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.

Javascript: What are the pros/cons of adding methods to an object class?

I've seen some people add methods to the object class like so:
Object.clone = function() {
}
Is this syntax just like any other function name only with a period or is this actually adding to the Object class? Is this the same as a prototype method? What would be the pros/cons of doing this (or using a prototype) versus just making a function clone?
In JavaScript everything is an object this means that you can attach properties to any object, just like you would with an object literal, for example:
var arr = [1,2,3];
arr.property = 'foo';
It is not good practice to do so on non-objects though.
Every object has a constructor, so an array has an Array constructor, an object has an Object contructor, etc. The prototype of an object is an object whose context is the instance, this happens on custom objects when you instantiate with new.
When you attach a method to the prototype it will be shared across all instances of that object. When you attach a function to the constructor, you're basically hiding a global (depending on the scope) under a namespace; the context is not the instance, and it doesn't depend on one. You could think of these functions as static methods.
Extending Object.prototype is troublesome, since this is the "mother object". Extending the Object constructor itself isn't as bad, but not the best practice. The best solution, just create your own namespace:
var MY = {};
MY.clone = function(){};
There's no need to add static functions to the built-in Object constructor. There are also issues with code robustness if you do this, as some current and future environments may introduce built-in methods of the same name and then you have name collisions.
Just add your methods to your own objects.

Dynamically create private methods in JavaScript

I'm creating a jQuery plugin that has an extend function allowing you to essentially create plugins for the plugin.
http://jsfiddle.net/eeBEJ/1/
If you take a look at the fiddle example you will see an $.fn.wPluginTest.extend function that allows you to pass in functions to extend the prototype. Is there anyway to also extend the local namespace to add private methods?
So for instance any functions passed with a _ in front would be set as private and not available publicly through a PluginTest object.
There are no private properties on javascript objects, and I'd say that it's fine to have them just prefixed with an underscore.
However, you could try:
$.fn.wPluginTest.extend = function(funcs) {
var proto = PluginTest.proto,
priv = Object.create(proto); // a private namespace inheriting from proto
for (func in funcs) {
if (func.charAt(0) != '_')
PluginTest.prototype[func] = funcs[func].bind(priv);
else
priv[func.slice(1)] = funcs[func];
// ^^^^^^^^^ not sure, might be confusing
}
}
Yet, those functions will not have access to the PluginTest instance they're called on - they're statically bound to the prototype objects - so it's probably a bad idea.
If any plugin needs real privateness, it should utilize variable scoping on its own.

Javascript: when to define functions inside constructor and when to use prototype?

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() {

JavaScript instance functions versus prototype functions [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use of 'prototype' vs. 'this' in Javascript?
My understanding of the different kinds of JavaScript functions are as follows:
function MyObj() {
this.propOne = true;
this.publicInstanceFunc = function() {
if (propOne)
return 'public instance function';
}
function privateFunc() {
return 'private function only visible inside this constructor';
}
}
MyObj.prototype.protoFunc = function() {
if (this.propOne)
return 'prototype function shared amongst all instances of MyObj';
}
Are these correct?
In what cases should one put functions on the prototype (e.g. protoFunc) vs. in the constructor (e.g. publicInstanceFunc)?
Is using this the correct way to access properties inside prototype functions?
You can actually add another level of privilege via wrapping the whole thing in a self-executing function:
var MyObj = (function() { // scoping
var privateSharedVar = 'foo';
function privateSharedFunction() {
// has access to privateSharedVar
// may also access publicSharedVar via explicit MyObj.prototype
// can't be called via this
}
function MyObj() { // constructor
var privateInstanceVar = 'bar';
this.publicInstanceVar = 'baz';
function privateInstanceFunction() {
// has access to all vars
// can't be called via this
};
this.publicInstanceMethod = function() {
// has access to all vars
// also known as a privileged method
};
}
MyObj.prototype.publicSharedVar = 'quux';
MyObj.prototype.publicSharedMethod = function() {
// has access to shared and public vars
// canonical way for method creation:
// try to use this as much as possible
};
return MyObj;
})();
Only 'public' properties can be accessed from outside via this.
For performance reasons, you should avoid what I called 'instance' methods: For each of these, a new function object must be created for each MyObject instance, whereas there's only a single function object per 'shared' method.
Are these correct?
Err. Well, it depends what you want to do. There is no one accepted canonical model for implementing class/instance-style inheritance in JavaScript.
But this:
if (propOne)
Is probably a mistake, in that this.propOne is a property of the owner object, whereas propOne by itself is a variable that hasn't been declared (this defaults to a global variable, but is usually a wrongness).
In what cases should one put functions on the prototype (e.g. protoFunc) vs. in the constructor (e.g. publicInstanceFunc)?
A function set on the prototype is the same function shared amongst all objects. The only way it can work out what instance it belongs to is by reading ‘this’ when it is called.
A function set on ‘this’ in the constructor is a new function for every instance of the MyObj. You can possibly use this as an alternative way to bind to the owner object based on closures instead of ‘this’, which can save writing out function-binding stuff. It's a different style of object-orientation which normally you wouldn't mix with the this-based style.
1) Yes your code is right.
2) I use functions defined within the constructor function when I want to access other members defined privately inside the scope of the constructor function itself, for example, when you want to create privileged methods.
Public functions defined on the constructor function, are more computationally expensive than adding a simple function to the object prototype, but they also give you much more flexibility.
3) Yes, if the property is public you are able to access it by using the this keyword inside of a prototype extended function, since this refers to the instance of your object.
Regarding the second point, you extend the prototype so that all the already created objects get the new method.
Also, allows you to add methods to the built-in objects (like adding trim() to string).

Categories