Dynamically create private methods in JavaScript - 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.

Related

Explanation of "Functional Pattern" from the book "JavaScript: The Good parts"

I am learning JS these days and I am unable to assimilate this Functional Pattern on page 52 of the book.
Functional
One weakness of the inheritance patterns we have seen so far is that we get no privacy.
All properties of an object are visible. We get no private variables and no
private methods. Sometimes that doesn’t matter, but sometimes it matters a lot. In frustration, some uninformed programmers have adopted a pattern of pretend
privacy. If they have a property that they wish to make private, they give it an odd looking name, with the hope that other users of the code will pretend that they cannot
see the odd looking members. Fortunately, we have a much better alternative in
an application of the module pattern.
We start by making a function that will produce objects. We will give it a name that
starts with a lowercase letter because it will not require the use of the new prefix. The
function contains four steps:
It creates a new object. There are lots of ways to make an object. It can make an
object literal, or it can call a constructor function with the new prefix, or it can
use the Object.beget method to make a new instance from an existing object, or
it can call any function that returns an object.
It optionally defines private instance variables and methods. These are just ordinary
vars of the function.
It augments that new object with methods. Those methods will have privileged
access to the parameters and the vars defined in the second step.
It returns that new object.
Here is a pseudocode template for a functional constructor (boldface text added for
emphasis):
var constructor = function (spec, my) {
var that, //other private instance variables;
my = my || {};
// Add shared variables and functions to my
that = a new object;
// Add privileged methods to that
return that;
}
The spec object contains all of the information that the constructor needs to make an
instance. The contents of the spec could be copied into private variables or transformed
by other functions. Or the methods can access information from spec as they
need it. (A simplification is to replace spec with a single value. This is useful when
the object being constructed does not need a whole spec object.)
Can anyone explain, what's going on there (in layman terms) and where such a pattern is useful?
Note: While the book you refer to is indeed an immensely helpful book, its quite ancient. Some of the "good" (and even "bad") parts have been replaced by even better alternatives and features in newest versions of JavaScript.
One weakness of the inheritance patterns we have seen so far is that
we get no privacy. All properties of an object are visible. We get no
private variables and no private methods.
A Javascript object has "properties", which can be other objects, or functions. Consider:
var obj = {a: 1, do: function(){console.log('done');} }
Nothing is stopping you from calling obj.a = 5, or obj.done().
But one might counter that that's not a good way of creating objects. We better have a prototype or class from which we can create new instances:
function Animal(name) {
this._name = name;
}
Animal.prototype.print = function(){console.log(this._name)};
or in more recent JavaScript versions:
class Animal {
constructor(name){
this._name = name;
}
print(){
console.log(this._name);
}
}
In frustration, some uninformed programmers have adopted a pattern of
pretend privacy. If they have a property that they wish to make
private, they give it an odd looking name, with the hope that other
users of the code will pretend that they cannot see the odd looking
members.
This is a comment on above code. When declaring JavaScript classes or functions, there is no official, standard, "fool proof AND syntactically elegant" way of keeping instance variables private. That is, an easy, clean way of declaring a variable that is only accessible to methods defined in that class or prototype (See this answer). So, people follow some agreed upon patterns, one of which is prefixing the variables names with a _. This actually provides no privacy to internal variables of a class instance.
With advent of the module system, one could write JavaScript code in a separate file/container and choose to make only specific objects visible to the outside world. A CommonJS example:
Animal.js:
const props = new WeakMap();
class Animal {
constructor(name){
props.set(this,{});
props.get(this).name = name;
}
set age(n){
props.get(this).age = age;
}
function print(){
console.log(props.get(this));
}
}
module.exports = Animal;
Above is one of the ways to declare a class with private properties not accessible from outside unless intentionally leaked. Notice how the object props is not exported to outside world.
Fortunately, we have a much better alternative in an application of
the module pattern.
You might think that the above module code is actually what this text means, but the above implementation is a newer version using latest features. The old school way the points in text illustrate is to expose an object creator (a.k.a factory) function. Everything declared inside the creator function and outside the created object is private by design:
function createAnimal(name){
var age = 0;
var animal = {};
animal.setAge = function(a){age = a;};
animal.getName = function(){return name;};
animal.print = function(){console.log({'name':name,'age':age});};
}
Inheritance here is a call to super creator and modifying the super instance:
function createDog(name, color){
var breed = 'unknown';
var dog = createAnimal(name);
dog.setBreed = function(b){breed = b;};
}
Essentially, the idea is to hide private variables within a closure. The variables being closed over are the (not shown) "other private instance variables", and the methods that actually are closing over these variables are the (also not shown) "privileged methods".
For example, take this function:
var createBoard = function (rows, cols) {
var cells = [];
var board = {};
for (var i = 0; i < rows; i++) {
cells[i] = [];
for (var j = 0; j < cols; j++) {
cells[i][j] = { player: null };
}
}
board.play = function (row, col, player) {
if (cells[row][col].player === null) {
cells[row][col].player = player;
}
};
board.getPlayer = function (row, col) {
return cells[row][col].player;
};
return board;
};
And let's assume we call this function to create an 8x8 gameboard:
var board = createBoard(8,8);
board.play(1,2,"Player1");
console.log(board.getPlayer(1,2));
board.play(1,2,"Player2"); // Doesn't actually do anything
// Note this code has no direct access to cells[][] except via the two
// methods we defined on the board object.
In this case, we return a board object. The board internally has access to a cells array, but we don't let anyone modify this except using our two methods, play (which occupies a board space only if it was previously unoccupied) and a getPlayer method that returns the player at a given space. Cells[][] is totally hidden to the user of this code - they couldn't cheat by changing our cell array directly.
JavaScript is an object-based language based on prototypes, rather than being class-based. 1
Compare that with Object-Oriented languages based on classes like PHP, Java, etc. In those languages, a class can be defined and member variables can have various visibility inside and outside the class. For instance, PHP has visibility set on three levels: public, protected or private.
Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited classes. Members declared as private may only be accessed by the class that defines the member.2
class MyClass {
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello() {
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
But in JavaScript, we don't really have such a concept of private variables (in the same sense). That is what the author is talking about when describing the module pattern.
So if we wanted to make an analagous construct in Javascript, we could make something like this:
var MyClass = function (rows, cols) {
//this could be used in prototype functions
var private = 'Private';
var members = {
public: 'Public';
getHello: function() {
return 'MyClass _ ' + private;
}
};
return members;
};

Static methods in 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();

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: 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