Empty Function use in Javascript - javascript

I am trying to understand a third party Javascript code.
But am not able to figure out what is the use of the below coding style.
function A(){
}
A.Prop = '23';
A.generate = function(n){
// do something
}
And then it is just used as :
A.generate(name);
Can someone explain what this code is doing.
I understand some bit of OO Javascript, but i wonder if this is any other form of extending an object with new properties to it. Though i dont see any "new" keyword being used, to create an object.
Any ideas ?
Thanks,

They are creating a namespace. There are many ways to do this, and all are more-or-less equivalent:
A = {
Prop : '23',
generate : function (n) {
// do something
}
};
Or, equivalently:
A = { };
A.Prop = '23';
A.generate = function (n) {
// do something
};
Also, if you like being verbose:
A = new Object();
A.Prop = '23';
A.generate = function (n) {
// do something
};
function is usually used to denote a "class" rather than a "namespace", like so:
A = (function () {
var propValue = '23'; // class local variable
return {
"Prop" : propValue,
"generate" : function (n) {
// do something
}
};
})();
// then I can use A in the same way as before:
A.generate(name);

It looks like they're using a dummy function to create a namespace.
You're right; this is useless.
They should use a normal object instead.

A function is an object, there's nothing inherently wrong with using it the way it's been used. However, since the function isn't actually used as a function, it would be better to use an Object. You could also use an Array (which is an object), but the same advice applies.
Also, identifiers starting with a capital letter are, by convention, reserved for constructors (unless they are all capitals, which are, by convention, for constants) so use a name starting with a lower-case letter.

Related

Is it possible to add a constructor afterwards to an existing object? Is it meaningful?

Assuming there is a construct like that:
var Foo = {
someVar : 13,
someMessage : function () {
return "Hello";
}
};
I would like to add a construct outside of Foo to initalize someVar, so that following action would be possible:
var foo = new Foo (someVar);
I know the so called constructor invocation pattern (which I am actually not looking for but I've also here a question):
var Foo = function (someVar) {
this.someVar = someVar;
};
Foo.prototype.getSomeVar = function () {
return this.someVar;
};
var foo = new Foo ("some content");
console.log (foo.getSomeVar());
How can I add a property (someSecondVar) to Foo outside of Foo?
attaching a property is simple and can be done just like how you would attach a function to a construct:
Foo.prototype.someSecondVar = 0;
Foo.prototype.someThirdVar = "blah";
You can not instantiate object literal (comparison to other programming languages does not work here) in JavaScript unfortunately. It would be (maybe) a good idea, you could save some paperwork.
"Constructor invocation pattern" is a try in the right direction and you can simply add a property in this way:
Foo.prototype.someSecondVar = "what ever";
EDIT: You can not instantiate an object literal but you can make a new object and select the object, that should be its prototype (from Douglas Crockford):
Please study the following example:
var Person = {
"name" : "Max",
"age" : 30,
"children" : ["Susi", "Ben"]
};
Object.create = function (obj) {
var F = function () {};
F.prototype = obj;
return new F();
};
var Person2 = Object.create(Person);
Person2.name = "John";
Person2.age = 40;
Person2.children = ["Sara"];
Person.city = "New York";
console.log(Person2);
The output shows 2 important things:
The new object has all properties from the old one
If you add some properties to old object afterwards, the newones will get it automatically
What you want to do can be accomplished by using the .prototype of the object. Keep in mind, altering the prototype is computationally expensive usually and it also alters all objects that are instances of the object who's prototype you're altering, which may or may not be what you want.
You can add a property the way Husman mentions in his answer.
If you really need to instantiate it and can't just place a value there with a custom function, look into getters and setters: MDN
by using getters/setters, you can add some conditional for whatever case you need the value of the property for, thus emulating a constructur, in a way.
Overall however, I'd advise rethinking your code structure. These kinds of approaches generally can only be justified if what you want to do is quite complicated and are usually not necessary if you re-think your code.

Putting arrays into custom objects

I am attempting to build my first custom object and it looks something like this:
function URLObject()
{
this.syllables = new Array();
etc...
this.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)
{
var SylCount = this.syllables.length;
alert("This is SylCount: " + SylCount);
}
}
var myobj = new URLObject();
myobj.AdtoSyllables("text");
The execution of the above code results in the JS engine printing out the following:
This is Sylcount: NAN
-or-
This is SylCount: undefined.
I have looked at information in Head First Javascript, in the Javascript bible, and on various JS websites. All of them cover in exhaustive detail the use of arrays of objects, but none of them discuss arrays within objects.
And yet I am doing something wrong here and I do not know what. Can anyone help?
Here you go:
function URLObject()
{
this.syllables = [];
etc...
}
URLObject.prototype.addToSyllables = function(aWord) {
var SylCount = this.syllables.length;
alert("This is SylCount: " + SylCount);
}
var myobj = new URLObject();
myobj.adtoSyllables("text");
.prototype adds the function declared after it to every object constructed by the constructor function. (in your case every object that was instantiated by new URLObject())
Firstly, the code as posted actually works for me on Chrome and Firefox; so this must depend on the JavaScript engine, or else there's something funky going on.
Update: I suspect what may be confusing you is some separate call to AddtoSyllables (in code you haven't shown us) where suddenly this.syllables is no longer defined. This is where the behavior of this can get confusing. I've created a jsFiddle to hopefully explain how it works a bit better for you.
http://jsfiddle.net/J3tUb/
That said, it is often very possible to write code like this without having to use this (or the prototype) at all. For instance:
function createURLObject() {
// Use closed-over locals instead of attaching properties.
var syllables = new Array();
function AddToSyllables(AWord) {
// Since syllables is closed over, it is accessible here
// (but WON'T be accessible outside this scope).
syllables.push(AWord);
return syllables.length;
}
// Expose whatever functionality you want to be "public"
// in the returned object.
return {
AddToSyllables: AddToSyllables
};
}
var myObj = createURLObject();
myObj.AddToSyllables("text");
It is, of course, valuable to understand JavaScript's quirky (and surprising, to most developers coming from other languages) behavior with respect to this. That said, once you do understand it, I suspect you will find that it can often be avoided altogether.
you need to do this :
function URLObject()
{
var that = this;
that.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)
etc...
Like this you can add method and attributes to one object.
The issue you are having is that the function AddtoSyllables is not a member function or method of the URLObject. It is just a nested function with no object attachments, so all usages of this will result in returning the dom window object. The correct way of declaring the AddtoSyllables function is this:
function URLObject()
{
//...
}
URLObject.prototype.AddtoSyllables = function (AWord)
{
var SylCount = this.syllables.length;
alert("This is SylCount: " + SylCount);
}
To explain the reasons of the behavior in the question, I'd like to clarify that objects in javascript are treated like a map, dictionary or a key-value pair (use the term what suits you best). Using the syntax x.y = value; is equivalent putting the value value into the map x with key y. Having the code:
this.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)
{
var SylCount = this.syllables.length;
alert("This is SylCount: " + SylCount);
}
adds the AddtoSyllables function as an entry to the object this points to.
The code
myobj.AdtoSyllables(...)
is equivalent to
myobj["AdtoSyllables"](...) // now a retreiaval operation
or even
var fn = myobj["AdtoSyllables"];
fn (...);
Inside the AdtoSyllables function, this is used. Against common expectations, it is not a pointer to the myobj.
The cause of this is that AddtoSyllables is treated as a static method of the URLObject class (as OOP guys would understand it), or even a loose static function (like in C). To make JS treat it like a member of the URLObject object (an instance method to OOP guys), JS must be told to do so. This is achieved through the URLObject.prototype.AddtoSyllables = .... which equivalents to declaration of an instance method.
From an alternative point of view:
function foo() { /* some code using `this` */ }
var bar = {};
var baz = {};
bar.foo = foo; // same as bar["foo"] = foo;
baz.foo = foo; // same az baz["foo"] = foo;
In the above code, this usages inside foo will neither point to bar, nor baz. At the same time bar.foo will point to the very same instance as baz.foo, for foo is also an object.

javascript "static imports"

Is there anything in javascript that is the equivalent of java static imports? For example, if I have a Math class that looks like
com.example.Math = function() {
function1(...) {}
function2(...) {}
}
Now some of these functions are naturally chained together such that the output to one is the input to another. I can do something like
com.example.Math.function2(com.example.Math.function1());
This is a little ugly looking, and I would really like to do something like:
function2(function1())
But I don't want to put function1 and function2 in the global namespace. Is this possible?
Yes, there is. It's called with.
with (com.example.Math) {
function2(function1());
}
That said:
Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.
For example:
var m = com.example.Math;
m.function2(m.function1());
How about:
var Math = com.example.Math;
and then:
Math.fn1( Math.fn2(...) );
I'm assuming of course that your code is not global code. (If you're not familiar with the concept of avoiding global code in JS, read about the module pattern.)
You can go one step further:
var Math = com.example.Math,
func1 = Math.func1,
func2 = Math.func2;
and then:
func1( func2(...) );
I would do something like this:
var O = function() {
var that = {};
var PI = Math.PI;
that.circ = function(r) {
return 2*PI*r;
};
return that;
};
var o = O();
console.log(o.circ(1));
Notice how PI is used without the Math namespace in the O.prototype.circ method.
In JavaScript, there is no distinction between a namespace and an object, so some would argue that Math is not a namespace, but since JavaScript doesn't support the concept, it is as much a namespace as com.mycompany.somelibrary.
One option is to use a closure to wrap the object. It doesn't necessarily eliminate the object itself, but it helps with readability and if you are using a JS compressor can help reduce the output file size:
(function(Math) {
Math.function2(Math.function1(...));
}(com.example.Math);)
You can also pass in multiple objects (ie: function(Math, Foo) {...}(com.example.Math, com.example.Foo)).
If you want to use just a few functions directly, just pass them in like this:
(function(function1, function2) {
function2(function1(...));
}(com.example.Math.function1, com.example.Math.function2);)
This, however, removes the relationship between the Math instance and the functions, so you might get some weird behavior if your methods depend on instance variables. As an example of how that won't work, imagine this class:
com.example.Counter = {
counter: 0,
increment: function() { this.counter++; }
}

Is my javascript coding style following best-practice?

What is the 'best practise' with regard to coding style.
Should I use _ for private members?
Should I use this._privateMember?
Please re-write my code in proper style if its wrong:
(function()){
var _blah = 1;
someFunction = function() {
alert(_blah);
};
someOtherFunction = function {
someFunction();
}
}();
I would read this and incorporate any part you agree with:
http://javascript.crockford.com/code.html
You do not have to agree with all of it
I don't think there is one. Use a prefix if you think it helps.
I use _ for private members because it distinguishes them which can be quite helpful in Javascript when you have variables coming from all over the place. But they do clutter the code a bit.
I don't use _ for variables that are declared using var. I do however, use _ to denote object members that shouldn't be access directly.
Some people (who are strange in my opinion :P), also prefix variables with a $ if it contains a jQuery object.
As long as you are consistent with what you do, there are no problems.
Aside from just the code you're showing now, you should use Capital Letters to distinguish constructor functions, and camelCase to name instances of objects.
function Foo (val) {
this.set(val);
};
Foo.prototype.get = function () {
return this._dontTouchMePlease;
};
Foo.prototype.set = function(val) {
this._dontTouchMePlease = parseInt(val, 10);
};
var aFoo = new Foo(6);
I think that its generally accepted that if a variable name starts with a _, you probably shouldn't touch it (accept in dire cirumcstances and even then, two keys and special codes should be provided).
If I'm remembering my Crockford correctly, you'll want to put var in front of the two inner functions, otherwise they will be implicit globals. If you want them to be globals, then that's moot. Either way, your second inner function declaration should probably end in a semicolon. This might be a misformating thing, but I think its generally accepted that the bodies of functions are indented one more level in. Also, I've never seen the (function()){/* stuff */}(); construction before, but that says pretty much nothing.
I'd write it these ways - one for if your just declaring a function and another for if your using an anonymous function and immediately applying it to get a result, because I don't which one you're trying to do (again, if you want the inner functions to be global, then this won't be what you intended):
//function declaration
var myFunction = function () {
var _blah = 1;
var someFunction () {
alert(_blah); //or console.log(_blah); for debugging purposes
};
var someOtherFunction () {
someFunction();
};
};
//using a one-of to assign a result
/* NOTE: if you are using this version, myResult will be undefined
(at least given the functions you provided), but like I said,
I don't recognize the construction you provided, and am therefore
assuming that you meant one of these two, which could be a perfectly
falacious assumption, and in that case, my apologies
*/
var myResult = function () {
var _blah = 1;
var someFunction () {
alert(_blah);
};
var someOtherFunction () {
someFunction();
};
}();
BTW, (and I don't want to overstep) Crockford's "JavaScript: The Good Parts" is a stellar reference for JavaScript syntax. He also has, on his website a JavaScript style guide of sorts (though I don't know how widely followed it is). Link is: http://javascript.crockford.com/code.html
I also use the "_" in c# for private/protected members. It is a fast way to see if the variable is a member-variable or not. And you can access it faster with code-completion because you don't get in mess with the public members (private: _blah , public property: Blah).
But are there any private members in javascript anyway? I think every variable defined as member is accessible from the outside.
So you don't have a public wrapper for the private member. And that means the "_" is a bit a overhead and the same can be achieved with "this.".
I prefer you to use the following stuffs which is preferably used around the world programmers.. see below
i = Int
f = Float
o = Object
r = Return
a = Array
e = Element
g = Global declaration
hook = a function which can be used for hooking with other functions
call = a function which can be used for making call from client to server system
sync = a function which can be used for SYNC
and so on.. you can prefix on your coding...

How to get class object's name as a string in Javascript?

Let's say I instantiate an object in Javascript like this:
var myObj = new someObject();
Now, is it possible to obtain the var object's name as string 'myObj' from within one of the class methods?
Additional details (edited):
The reason why I would like to get the name of the variable holding reference to the object is that my new myObj would create a new clickable DIV on the page that would need to call a function myObj.someFunction(). As I insert the new DIV I need to know the name of the variable holding reference to the object. Is there maybe a better way of doing this?
You are right, sorry for the mixup in terminology.
The reason why I would like to get the name of the variable holding reference to the object is that my new myObj would create a new clickable DIV on the page that would need to call a function myObj.someFunction(). As I insert the new DIV I need to know the name of the variable holding reference to the object. Is there maybe a better way of doing this?
Shog9 is right that this doesn't make all that much sense to ask, since an object could be referred to by multiple variables. If you don't really care about that, and all you want is to find the name of one of the global variables that refers to that object, you could do the following hack:
function myClass() {
this.myName = function () {
// search through the global object for a name that resolves to this object
for (var name in this.global)
if (this.global[name] == this)
return name
}
}
// store the global object, which can be referred to as this at the top level, in a
// property on our prototype, so we can refer to it in our object's methods
myClass.prototype.global = this
// create a global variable referring to an object
var myVar = new myClass()
myVar.myName() // returns "myVar"
Note that this is an ugly hack, and should not be used in production code. If there is more than one variable referring to an object, you can't tell which one you'll get. It will only search the global variables, so it won't work if a variable is local to a function. In general, if you need to name something, you should pass the name in to the constructor when you create it.
edit: To respond to your clarification, if you need to be able to refer to something from an event handler, you shouldn't be referring to it by name, but instead add a function that refers to the object directly. Here's a quick example that I whipped up that shows something similar, I think, to what you're trying to do:
function myConstructor () {
this.count = 0
this.clickme = function () {
this.count += 1
alert(this.count)
}
var newDiv = document.createElement("div")
var contents = document.createTextNode("Click me!")
// This is the crucial part. We don't construct an onclick handler by creating a
// string, but instead we pass in a function that does what we want. In order to
// refer to the object, we can't use this directly (since that will refer to the
// div when running event handler), but we create an anonymous function with an
// argument and pass this in as that argument.
newDiv.onclick = (function (obj) {
return function () {
obj.clickme()
}
})(this)
newDiv.appendChild(contents)
document.getElementById("frobnozzle").appendChild(newDiv)
}
window.onload = function () {
var myVar = new myConstructor()
}
Short answer: No. myObj isn't the name of the object, it's the name of a variable holding a reference to the object - you could have any number of other variables holding a reference to the same object.
Now, if it's your program, then you make the rules: if you want to say that any given object will only be referenced by one variable, ever, and diligently enforce that in your code, then just set a property on the object with the name of the variable.
That said, i doubt what you're asking for is actually what you really want. Maybe describe your problem in a bit more detail...?
Pedantry: JavaScript doesn't have classes. someObject is a constructor function. Given a reference to an object, you can obtain a reference to the function that created it using the constructor property.
In response to the additional details you've provided:
The answer you're looking for can be found here: JavaScript Callback Scope (and in response to numerous other questions on SO - it's a common point of confusion for those new to JS). You just need to wrap the call to the object member in a closure that preserves access to the context object.
You can do it converting by the constructor to a string using .toString() :
function getObjectClass(obj){
if (typeof obj != "object" || obj === null) return false;
else return /(\w+)\(/.exec(obj.constructor.toString())[1];}
You might be able to achieve your goal by using it in a function, and then examining the function's source with toString():
var whatsMyName;
// Just do something with the whatsMyName variable, no matter what
function func() {var v = whatsMyName;}
// Now that we're using whatsMyName in a function, we could get the source code of the function as a string:
var source = func.toString();
// Then extract the variable name from the function source:
var result = /var v = (.[^;]*)/.exec(source);
alert(result[1]); // Should alert 'whatsMyName';
If you don't want to use a function constructor like in Brian's answer you can use Object.create() instead:-
var myVar = {
count: 0
}
myVar.init = function(n) {
this.count = n
this.newDiv()
}
myVar.newDiv = function() {
var newDiv = document.createElement("div")
var contents = document.createTextNode("Click me!")
var func = myVar.func(this)
newDiv.addEventListener ?
newDiv.addEventListener('click', func, false) :
newDiv.attachEvent('onclick', func)
newDiv.appendChild(contents)
document.getElementsByTagName("body")[0].appendChild(newDiv)
}
myVar.func = function (thys) {
return function() {
thys.clickme()
}
}
myVar.clickme = function () {
this.count += 1
alert(this.count)
}
myVar.init(2)
var myVar1 = Object.create(myVar)
myVar1.init(55)
var myVar2 = Object.create(myVar)
myVar2.init(150)
// etc
Strangely, I couldn't get the above to work using newDiv.onClick, but it works with newDiv.addEventListener / newDiv.attachEvent.
Since Object.create is newish, include the following code from Douglas Crockford for older browsers, including IE8.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o
return new F()
}
}
As a more elementary situation it would be nice IF this had a property that could reference it's referring variable (heads or tails) but unfortunately it only references the instantiation of the new coinSide object.
javascript: /* it would be nice but ... a solution NOT! */
function coinSide(){this.ref=this};
/* can .ref be set so as to identify it's referring variable? (heads or tails) */
heads = new coinSide();
tails = new coinSide();
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);
alert(["FF's Gecko engine shows:\n\ntoss.toSource() is ", toss.toSource()])
which always displays
[object Object]
and Firefox's Gecko engine shows:
toss.toSource() is ,#1={ref:#1#}
Of course, in this example, to resolve #1, and hence toss, it's simple enough to test toss==heads and toss==tails. This question, which is really asking if javascript has a call-by-name mechanism, motivates consideration of the counterpart, is there a call-by-value mechanism to determine the ACTUAL value of a variable? The example demonstrates that the "values" of both heads and tails are identical, yet alert(heads==tails) is false.
The self-reference can be coerced as follows:
(avoiding the object space hunt and possible ambiguities as noted in the How to get class object's name as a string in Javascript? solution)
javascript:
function assign(n,v){ eval( n +"="+ v ); eval( n +".ref='"+ n +"'" ) }
function coinSide(){};
assign("heads", "new coinSide()");
assign("tails", "new coinSide()");
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);
to display heads or tails.
It is perhaps an anathema to the essence of Javascript's language design, as an interpreted prototyping functional language, to have such capabilities as primitives.
A final consideration:
javascript:
item=new Object(); refName="item"; deferAgain="refName";
alert([deferAgain,eval(deferAgain),eval(eval(deferAgain))].join('\n'));
so, as stipulated ...
javascript:
function bindDIV(objName){
return eval( objName +'=new someObject("'+objName+'")' )
};
function someObject(objName){
this.div="\n<DIV onclick='window.opener."+ /* window.opener - hiccup!! */
objName+
".someFunction()'>clickable DIV</DIV>\n";
this.someFunction=function(){alert(['my variable object name is ',objName])}
};
with(window.open('','test').document){ /* see above hiccup */
write('<html>'+
bindDIV('DIVobj1').div+
bindDIV('DIV2').div+
(alias=bindDIV('multiply')).div+
'an aliased DIV clone'+multiply.div+
'</html>');
close();
};
void (0);
Is there a better way ... ?
"better" as in easier? Easier to program? Easier to understand? Easier as in faster execution? Or is it as in "... and now for something completely different"?
Immediately after the object is instantiatd, you can attach a property, say name, to the object and assign the string value you expect to it:
var myObj = new someClass();
myObj.name="myObj";
document.write(myObj.name);
Alternatively, the assignment can be made inside the codes of the class, i.e.
var someClass = function(P)
{ this.name=P;
// rest of the class definition...
};
var myObj = new someClass("myObj");
document.write(myObj.name);
Some time ago, I used this.
Perhaps you could try:
+function(){
var my_var = function get_this_name(){
alert("I " + this.init());
};
my_var.prototype.init = function(){
return my_var.name;
}
new my_var();
}();
Pop an Alert: "I get_this_name".
This is pretty old, but I ran across this question via Google, so perhaps this solution might be useful to others.
function GetObjectName(myObject){
var objectName=JSON.stringify(myObject).match(/"(.*?)"/)[1];
return objectName;
}
It just uses the browser's JSON parser and regex without cluttering up the DOM or your object too much.

Categories

Resources