Revealing module pattern naming convention - javascript

I'd like to avoid having to remember two names for a method, one for public and one for private access. In that sense, in which case would a script fail if you use same name for both? When would following code fail?
var TestClass = function() {
function showMessage(text) {
$("div").text(text);
}
return {
showMessage: showMessage
};
}();
I've tried it in this fiddle, and it works properly in FF, IE, Chrome, Safari. JSLint has nothing to say about it either.
I've regularly see people naming private method _showMessage or showMessageFn. Is there a good reason for this?
Answer I'm looking for is that it either fails in some situations, may create confusion, or that it's just JavaScript people inventing conventions to seem smart.

This works fine - you're defining a function called showMessage() in the context of your inner function, then assigning it to the showMessage property of your exported object literal.
A property name can be any valid identifier, so showMessage is of course perfectly valid. In your example, function showMessage(text) creates an identifier called showMessage in the inner scope, referencing a function definition. You then create a separate identifier called showMessage as a property name on the object literal, which is assigned the value of the function referenced by the the inner identifier. The fact that both identifiers have the same name is irrelevant as they do not exist in the same scope.
Only problem I can see is that you should wrap the function invocation in parens, otherwise it is not immediately clear to the reader that the function is self-invoking.
So this:
var TestClass = function() {
...
}();
Becomes this:
var TestClass = (function() {
...
}());
The reason private methods are often prefixed with an underscore is simply a widely used convention - it shows that the method is intended to be private (Javascript doesn't support access modifiers, so any property or method that isn't encapsulated in a closure can be accessed from an outer scope). The accepted answer to this StackOverflow quesion sums it up perfectly.

What you are doing here is returning an object that contains the object of the function you defined.
I think that basically it's a way to show whether you are accessing the function in the same scope that it was created or in a different scope.

Related

Binding a name for JavaScript function using variable name

I'm having an issue with the following:
I think the issue is clear, the anonymous function does not take the name of its variable .
Therefore, how do I extend Function Object Constructor to give a name to a function according to the affected variable?
You can just do this:
var i_am = function i_am() { return "I Sure Am!"; }
That syntax has always been valid, but in the past there have been some browser quirks about that. If those quirks are of concern, you can always do this:
function i_am() {
return "I Sure Am!";
}
var i_am = i_am;
That's a little bit fishy, because the binding for "i_am" in the local scope is highjacked from the function, but the function retains the internal binding of the name.
Now, there's no way to retroactively give a function an internally-bound name. Functions are pretty much frozen upon creation (and if you think about language semantics and optimization, that's the way it should be).
You can't.
The name of the function is determined as you create the function.
If you use an unnamed function expression, then the function will be created (with no name) and then assigned to the variable.
Since the variable doesn't come anywhere near the function before then, it can't be used to determine the function's name.
If you want to give a function created with a function expression a name, then use a named function expression.
var addFn = function addFn () {};
(Warning: Old versions of Internet Explorer have memory leak and scope related bugs surrounding named function expressions).

Can you get the property name through which a function was called?

I've done a lot of searching and some playing around, and I'm pretty sure the answer to this question is no, but I'm hoping a JavaScript expert might have a trick up his sleeve that can do this.
A JavaScript function can be referenced by multiple properties, even on completely different objects, so there's no such thing as the object or property that holds the function. But any time you actually call a function, you must have done so via a single object (at the very least, the window object for global function calls) and property on that object.
(A function can also be called via a function-local variable, but we can consider the function-local variable to be a property of the activation object of the scope, so that case is not an exception to this rule.)
My question is, is there a way to get that property name that was used to call the function, from inside the function body? I don't want to pass in the property name as an argument, or closure around a variable in an enclosing scope, or store the name as a separate property on the object that holds the function reference and have the function access that name property on the this object.
Here's an example of what I want to do:
var callName1 = function() { var callName = /* some magic */; alert(callName); };
var obj1 = {'callName2':callName1, 'callName3':callName1 };
var obj2 = {'callName4':callName1, 'callName5':callName1 };
callName1(); // should alert 'callName1'
obj1.callName2(); // should alert 'callName2'
obj1.callName3(); // should alert 'callName3'
obj2.callName4(); // should alert 'callName4'
obj2.callName5(); // should alert 'callName5'
From my searching, it looks like the closest you can get to the above is arguments.callee.name, but that won't work, because that only returns the name that was fixed to the function object when it was defined, and only if it was defined as a named function (which the function in my example is not).
I also considered that maybe you could iterate over all properties of the this object and test for equality with arguments.callee to find the property whose value is a reference to the function itself, but that won't work either (in the general case), because there could be multiple references to the function in the object's own (or inherited) property set, as in my example. (Also, that seems like it would be kind of an inefficient solution.)
Can this be done?
Short answer:
No, you cannot get "the property name" used to call your function.
There may be no name at all, or multiple names across different scopes, so "the property name" is pretty ill defined.
arguments.callee is deprecated and should not be used.
There exists no solution that does not use arguments or closure.
Long answer:
As thefourtheye commented, you should rethink what you are trying to do and ask that instead in a new question. But there are some common misconceptions, so I will try to explain why you cannot get the "simple property name".
The reason is because it is not simple.
Before we go ahead, let us clarify something. Activation Objects are not objects at all.
The ECMAScript 5.1 specification calls them Environment Records (10.2.1), but a more common term is Scope chain.
In a browser the global scope is (often) the window object, but all other scopes are not objects.
There may be an object that you use to call a function, and when you call a function you must be in some scope.
With few exceptions, scopes are not objects, and objects are not scopes.
Then, there are many names.
When you call a function, you need to reference it, such as through an object property. This reference may have a name.
Scope chain has declarations, which always have a name.
A Function (the real function, not reference) may also have a function name - your arguments.callee.name - which is fixed at declaration.
Not only are they different names, they are not (always) the "the property name" you are seeking.
var obj = { prop : function f(){} }, func = obj.prop;
// "obj" and "func" are declarations.
// Function name is "f" - use this name instead of arguments.callee
// Property name is "prop"
func(); // Reference name is "func"
obj.prop(); // Reference names are "obj" and "prop"
// But they are the same function!
// P.S. "this" in f is undefined (strict mode) or window (non-strict)
So, a function reference may comes from a binding (e.g. function declaration), an Object (arguments.callee), or a variable.
They are all References (8.7). And reference does have a name (so to speak).
The catch is, a function reference does not always come from an object or the scope chain, and its name is not always defined.
For example a common closure technique:
(function(i){ /* what is my name? */ })(i)
Even if the reference does have a name, a function call (11.2.3) does not pass the reference or its name to the function in any way.
Which keeps the JavaScript engine sane. Consider this example:
eval("(new Function('return function a(){}'))()")() // Calls function 'a'.
The final function call refers the eval function, which refers the result of a new global scope (in strict mode, anyway), which refers a function call statement, which refers a group, which refers an anonymous Function object, and which contains code that expresses and returns a function called 'a'.
If you want to get the "property name" from within a, which one should it get? "eval"? "Function"? "anonymous"? "a"? All of them?
Before you answer, consider complications such as function access across iframes, which has different globals as well as cross origin restriction, or interaction with native functions (Function.prototype.bind for example), and you will see how it quickly becomes hell.
This is also why arguments.caller, __caller__, and other similar techniques are now all deprecated.
The "property name" of a function is even more ill defined than the caller, almost unrealistic.
At least caller is always an execution context (not necessary a function).
So, not knowing what your real problem is, the best bet of getting the "property name" is using closure.
there is no reflection, but you can use function behavior to make adding your own fairly painless, and without resorting to try/catch, arguments.callee, Function.caller, or other strongly frowned-upon behavior, just wasteful looping:
// returning a function from inside a function always creates a new, unique function we can self-identify later:
function callName() {
return function callMe(){
for(var it in this) if(this[it]===callMe) return alert(it);
}
};
//the one ugly about this is the extra "()" at the end:
var obj1 = {'callName2':callName(), 'callName3':callName() };
var obj2 = {'callName4':callName(), 'callName5':callName() };
//test out the tattle-tale function:
obj1.callName2(); // alerts 'callName2'
obj2.callName5(); // alerts 'callName5'
if you REALLY want to make it look like an assignment and avoid the execution parens each time in the object literal, you can do this hacky routine to create an invoking alias:
function callName() {
return function callMe(){
for(var it in this) if(this[it]===callMe) return alert(it);
}
};
//make an alias to execute a function each time it's used :
Object.defineProperty(window, 'callNamer', {get: function(){ return callName() }});
//use the alias to assign a tattle-tale function (look ma, no parens!):
var obj1 = {'callName2': callNamer, 'callName3': callNamer };
var obj2 = {'callName4': callNamer, 'callName5': callNamer };
//try it out:
obj1.callName2(); // alerts 'callName2'
obj2.callName5(); // alerts 'callName5'
all that aside, you can probably accomplish what you need to do without all the looping required by this approach.
Advantages:
works on globals or object properties
requires no repetitive key/name passing
uses no proprietary or deprecated features
does not use arguments or closure
surrounding code executes faster (optimized) than
a try/catch version
is not confused by repeated uses
can handle new and deleted (renamed) properties
Caveats:
doesn't work on private vars, which have no property name
partially loops owner object each access
slower computation than a memorized property or code-time repetition
won't survive call/bind/apply
wont survive a setTimeout without bind() or a wrapper function
cannot easily be cloned
honestly, i think all the ways of accomplishing this task are "less than ideal", to be polite, and i would recommend you just bite the coding bullet and pass extra key names, or automate that by using a method to add properties to a blank object instead of coding it all in an object literal.
Yes.
Sort Of.
It depends on the browser. (Chrome=OK, Firefox=Nope)
You can use a factory to create the function, and a call stack parsing hack that will probably get me arrested.
This solution works in my version of Chrome on Windows 7, but the approach could be adapted to other browsers (if they support stack and show the property name in the call stack like Chrome does). I would not recommend doing this in production code as it is a pretty brittle hack; instead improve the architecture of your program so that you do not need to rely on knowing the name of the calling property. You didn't post details about your problem domain so this is just a fun little thought experiment; to wit:
JSFiddle demo: http://jsfiddle.net/tv9m36fr/
Runnable snippet: (scroll down and click Run code snippet)
function getCallerName(ex) {
// parse the call stack to find name of caller; assumes called from object property
// todo: replace with regex (left as exercise for the reader)
// this works in chrome on win7. other browsers may format differently(?) but not tested.
// easy enough to extend this concept to be browser-specific if rules are known.
// this is only for educational purposes; I would not do this in production code.
var stack = ex.stack.toString();
var idx = stack.indexOf('\n');
var lines = ex.stack.substring(idx + 1);
var objectSentinel = 'Object.';
idx = lines.indexOf(objectSentinel);
var line = lines.substring(idx + objectSentinel.length);
idx = line.indexOf(' ');
var callerName = line.substring(0, idx);
return callerName;
}
var Factory = {
getFunction: function () {
return function () {
var callName = "";
try {
throw up; // you don't *have* to throw to get stack trace, but it's more fun!
} catch (ex) {
callName = getCallerName(ex);
}
alert(callName);
};
}
}
var obj1 = {
'callName2': Factory.getFunction(),
'callName3': Factory.getFunction()
};
var obj2 = {
'callName4': Factory.getFunction(),
'callName5': Factory.getFunction()
};
obj1.callName2(); // should alert 'callName2'
obj1.callName3(); // should alert 'callName3'
obj2.callName4(); // should alert 'callName4'
obj2.callName5(); // should alert 'callName5'

Getting “private method” in a “public function” class using CoffeeScript

I'm doing a series of tests with classes and CoffeeScript/JavaScript. See the following code:
class Example
someFunction = ->
alert #getText()
constructor: ->
#text = 'Hello world! ;)'
someFunction()
getText: ->
#text
### Instance ###
example = new Example
It's just an example, when compiling I get the error:
Uncaught TypeError: Object [object global] has no method 'getText'
You know how I can solve this problem?
http://jsfiddle.net/P4Xdz/
If you really want to do this sort of thing, you'll have to manually provide the correct # (AKA this) by hand with call or apply:
constructor: ->
#text = 'Hello world! ;)'
someFunction.call(#)
Demo: http://jsfiddle.net/ambiguous/6KZrs/
The problem is that someFunction is not a method of any kind, it is just a simple function. If you need it to behave like a method then you have to "methodize" it manually by providing the desired # when you call it. This (and epidemian) suggests an alternative approach: explicitly pass the object as an argument:
someFunction = (ex) ->
console.log ex.getText()
constructor: ->
#text = 'Hello world! ;)'
someFunction(#)
Demo: http://jsfiddle.net/ambiguous/hccDr/
Keep in mind that there is no public or private in JavaScript and so there is no public or private in CoffeeScript. You can sort of fake it but fakery has holes and tends to require more chicanery (such as manually supplying the # with call) to make it work. If you look at the JavaScript version of your code, you'll see that someFunction is just this:
var someFunction = function() { ... };
Just a function in a variable that is scoped to the class function, nothing more. Also keep in mind that since someFunction is local to the Example class function, it won't be visible in any way to subclasses.
This may be obvious but... coffescript isn't able to do anything conceptually you couldn't already do in javascript. Right now your someFunction definition is a local variable, and is not declared as a property on the instance (unlike getText).
When you use '#' within someFunction I'm assuming you expect it to refer to the instance of Example, which would be convenient in your case, however someFunction isn't defined on example.
If you used the => notation it still wouldn't bind it to the instance (it would refer to the class function). Now this may seem inconvenient, or an odd design choice, but its actually consistent. Once again, someFunction isn't on the instance, its defined as a local variable within the Example class function.
If you use ->, '#' refers to javascripts 'this' for that function (which is the local variable and obviously doesn't contain getText). If you use => it refers to javascripts 'this' at the time of the definition, which is at this point the Example class function. The Example instance, which is what you want to refer to, isn't even created yet (though you wish to refer to it).
The reason # refers to the example instance within functions like getText is because javascripts this keyword refers to the object your defined on. Coffeescript is really no different, other then providing you a convenient syntax of referring to the 'this' at the time of a functions definition.
TLDR:
You can't really accomplish what your looking for, and your probably going to have to give up on the idea of a 'private' function on an instance
The best I can see you doing is what you've already described in your comments above
Example.prototype.getText()
Because the two ways you'll be able to refer to this method are through the instance and the Example.prototype (which the function is defined on). Since your method isn't defined on the instance, then you cannot use 'this'. However if you call the method from the prototype, your getText function will fail anyway.
getText: ->
#text
the #text refers to what getText is defined on, and in this context its the prototype (not the instance). And text is undefined on the prototype.
If you want to have this method function the way you expect your probably going to have to make it not 'private'. Javascript/Coffeescript do not have access modifiers like public and private, a private method is really a function defined in a particular scope. In this case that scope doesn't have access to what you want, and the this keyword doesn't refer to what you need.
You're using someFunction = rather than someFunction:. This won't do what you expect.
You're calling someFunction, when in fact you probably want to be calling #someFunction.
In the way you've written your example, 'someFunction' is an anonymous function that has not been bound to anything. So, 'someFunction's 'this' is bound to the global object, which explains your error. You can fix it by using fat arrows to define 'someFunction' and placing 'someFunction' in Example's constructor. This will cause 'someFunction' to be bound to your Example instance. If you were to bind 'someFunction' by using a fat arrow, but leave it outside the constructor as you originally had, 'someFunction' would be bound to the Example constructor, causing 'someFunction' to call a non existent static method --getText-- of Example.
Here's how to get rid of your error:
class Example
constructor: ->
someFunction = =>
alert #getText()
#text = 'Hello world! ;)'
someFunction()
getText: =>
#text
### Instance ###
example = new Example

Javascript Mutable Parameter?

This is just a technical question about javascript. In javascript, one member of my group found something odd with javascript object creation. For some reason, the parameters in the object are already treated as members without assigning them to any member variables created in the constructor of the object. The parameters are mutable also as seen in the code block below.
Here's the code to show the testing we have being doing.
function NamedItem(name)
{
name = 5;
this.getName = function ()
{
return name;
}
}
document.write(namedItem.getName() + "\n"); //5
Is this legitimate? Is it dangerous?
That's called a closure.
Nested functions can access variables from their parent function and extend the variables' lifetimes beyond the execution of the parent function.
It has nothing to do with objects.
Just to be clear there are some potentially silly things about what you're doing. Let me explain a few principles.
If you declare a variable or variables as arguments to a function such as function(arg1, arg2), in terms of the variables themselves (and not their values) it is essentially the same as saying at the top of your function var arg1; var arg2;. The are declared for you automatically. Even if you try and redeclare them, they'll still work with the passed in arguments!
Functions are objects. Objects can have properties. Therefore functions can have properties, such as this.getName = function().
Like the #SLaks pointed out you're creating a closure in your version of the getName method. A closure captures the state of things above it when it's created. Therefore if there is a name variable in its scope when it's created, it will have access to that name variable in it's scope. It's a very normal practice in JavaScript and you've managed to create a private property (name) with a public accessor function (getName). Well done.
I assume you're using creating instances of NamedItem with the new keyword like this. var item = new NamedItem("javascripter"). Another way (and one that uses less memory than what you are doing is to add the getName() function to the prototype for NamedItem like I show below. The drawback to the prototype approach is that you could just as easily access _name directly. There are no private properties in the traditional sense in JavaScript, but some people use the underscore prefix to indicate to people that they're private and not to use them. This approach (prototypes) use less memory than your approach because if you create multiple instances of NamedItem they all share a single prototype.
Using the prototypes instead:
function NamedItem(name) {
this._name = name
}
NamedItem.prototype.getName = function() {
return this._name
}
Hope that gives you some things to think about!
J

What kind of a pattern/object is this in Javascript?

I see this pattern a lot (which I actually use) but I want an explanation as to how it works.
var mystuff = function() {
var blah = function() {
};
return {
setup: function() {
blah();
};
};
}();
Then usage is very OOP like:
mystuff.setup();
What that's doing is returning a public interface to your object. It looks like you are using the public setup() function to access the private blah() function. This is one method of emulating public and private member functions in Javascript objects.
Since mystuff is defined with that trailing () at the bottom, it's executed immediately when the parser reaches mystuff.setup(), and actually returns an anonymous object (your public interface) with the setup() method.
Others have explained how it works. This is just somemore background info on the topic.
It's called the "Module pattern" (coined by Douglas Crockford I believe, but blogged about earlier).
It gives you three main benefits:
A namespace (the value to the left of "function")
A private "space" to put stuff in (vars, functions, etc) that don't need or should not pollute the global namespace (this is the stuff before the return statement)
A public "space" to put stuff that you want accessible to users of your namespace (this is the return statement)
all in a fairly readable form.
This is simply an example of nested functions in JavaScript. Although the method of calling them may seem "OOP-like" on the surface, this style very much belongs to the functional paradigm.
In essence, however, there's nothing too fancy going on. JavaScript is known as a language in which "everything is a function", which is close enough to the truth. All it means is that any function declared belongs strictly to its parent scope.
It's from a functional programming approach to object oriented programming. Local variables in the outer (anonymous) function (the constructor) are accessible to any function defined within the constructor, but not elsewhere, making the local variables private. Where it differs from the purely functional approach is that the constructor returns an object literal rather than another function. The local variables are accessible by inner functions due to what's termed a closure.
It's use is to create private fields & methods, in the form of local variables.
but I want an explanation as to how it works.
Let's desect it piece by piece.
function() { .... } is a syntax for anonymous function.
function() { .... }() is defining and calling the anonymous function on the same line.
The return value of the function in your sample is an object defined using JSON notation (Javscript Object Notation)
{ setup : .... } is an object with one attribute: it's called setup, and it happens to be a function, in your case.
so, mystuff got the return value, which is an object with a property (function) called setup, and mystuff.setup() invokes this setup function.
Now, the interesting part is probably how setup just calls the blah function, defined inside that enclosing anonymous function.
I believe the technical term here is closure (see the section forming closures) (Also see the wikipedia definition)
Essentially the function becomes like a module of its own, with variables bound to it.
It's explained in crescentfresh's answer
First of all, please avoid this syntax:
var mystuff=function(){...}();
It is bad coding practice since it isn't completely cross-browser as a few browsers will error here.
Get used to putting parentheses around the function like so:\
var mystuff=(function(){...})();
Nextly, regarding the pattern. This pattern is more commonly known as simply "encapsulation" in JavaScript. Closures is another possibly but more specifically it is purely encapsulation in this case.
Encapsulation simply means you are making some members private. What is private in this case? Well the blah variable is private in this case. Please get into the habit of proceeding private members with an underscore to indiciate they are private. It is good coding practice to distinguish public methods from private methods with an underscore.
<script type="text/javascript">
var obj=(function(){
//private members
var _p={};//toss all private members into a single object.
_p.list=[];
_p.init=function(){
_p.list=[];
};
//public members. use "this" to reference object followed by the method.
//however obj._p.list won't be accessible to the global scope
return {
reset:function()
{
_p.init();
}
,addName:function(str)
{
_p.list.push(''+str);//limit to strings
}
,getNames:function()
{
return _p.list.slice(0);//return a clone
}
,alertNames:function()
{
alert(this.getNames().join(","));
}
,getPrivateObj:function()
{
return _p;
}
};
})();
obj.alertNames();
obj.addName("Nandan");
obj.addName("Ram");
obj.alertNames();
obj.reset();
obj.alertNames();
obj.addName("Vinoth");
obj.addName("Kevin");
obj.alertNames();
alert(typeof obj._p);//undefined
var privateObj=obj.getPrivateObj();
alert(typeof privateObj);
alert(privateObj.list.join("|"));
</script>

Categories

Resources