JavaScript Constructor Function Instantiated Object Prefix Convention - javascript

In JavaScript, is there a naming convention for objects instantiated from constructor functions?
For example, if I had a constructor function set up like so:
function Dance(style, timing) {
this.style = style; // for reflection
this.timing = timing;
}
var waltz = new Dance('waltz' , '3/4');
var rumba = new Dance('rumba' , '4/4');
So a console command would look like this:
console> waltz.timing 3/4
console> rumba.timing  4/4
What I'm looking for is a convention saying that waltz and rumba are instantiated objects; like prefixing with an "o"?
var oWaltz = new Dance('waltz' , '3/4');
var oRumba = new Dance('rumba' , '4/4');
I actually (gasp!) Googled and did a little homework before asking this question, and came up with the following:
a. Crockford's "JavaScript: The Good Parts." Most notably, he recommends using a capital letter on the actual constructor function:
There is a convention that all constructor functions are named with an initial capital (Pg. 49).
Fine, but I don't see any convention regarding instances of these constructor functions. All his examples are prefixed with "my," like so..
var myTango = new Dance('tango' , '4/4');
console> myTango.timing  4/4
...which is great for an example, but is not a reasonable convention.
b. I also dug up this thread, which calls the "o" prefix "Hungarian dialect," and also calls it obsolete:
What does "o" mean as a variable prefix?
c. We also have the convention of prefixing variables that contain jQuery wrapped set with a "$" like the following, which would select all <button> tags on the page, create a jQuery wrapped set, and assign it to the $buttons variable:
$buttons = $('button');
d. Finally, a simple Google search for "JavaScript object instance prefix" yields the underscore "_" convention for private functions; in this example if we were to add a private prototype function, it might look like this:
Dance.prototype._lessonCost = function(minutes) { return ($1.50 * minutes); }
Which, again, is not really of any help, which brings me here.
If you made it this far, thank for answering :^) I feel like I'm missing something; like there's a fundamental flaw with my technique.

I'm not sure if its a standard but usually instances of objects start with a lowercase letter and then camel case the rest. I'm not aware of any prefixes and think this would just cause a bunch of extra code to pass to the client.
var myObject = new MyObject();

Related

How to deal with and discern inheritance conflicts in JavaScript?

So the code below reflects the pseudo-classical version of inheritance in JavaScript.
function SynthOne() { // constructor 1
this.sound1 = "piano";
};
function SynthTwo() { // constructor 2
this.sound2 = "bass";
}
SynthOne.prototype = new SynthTwo; // overwrite constructor 1's prototype with constructor 2's
var synthsCombined = new SynthOne; // assign constructor 1 to variable
// this variable now has access to both constructors properties & methods
document.write(synthsCombined.sound1 + " ")
document.write(synthsCombined.sound2)
But let's change this to make sound1 and sound2 to simply sound.
Let's also assume that I really wanted to create an inheritance chain to access both of these "sounds" even if they were named the same thing. Is there a pattern in the JavaScript community or a coding convention that exist to deal with this kind of situation? Or am I just stuck?
Thank you
Child properties hide properties of the same name further up the prototype chain. Technically, you can still get access to the parent property like this:
Object.getPrototypeOf(synthsCombined).sound
Or the non-standard:
synthsCombined.__proto__.sound
But this probably isn't something you want to do. If you need both values, then name them different things.
it was simply something that entered my mind and I was curious about. I can see a situation where at the very least you combine constructors not realizing they have similar property/method names.
You hardly inherit from classes whose set of properties1 you do not know. If you subclass something, you often want to explicitly overwrite properties with more specific values - that's just what the shadowing is for.
In case you want to extend the set, you'd have to choose an unallocated name. In case of interface clashes (e.g. when extending the implementation), that's just a bug and either the base class or the child classes would need to change their identifier. Using descriptive names will lower the risk.
How to deal with this kind of situation?
If it's unwanted, fix the bug (this is not JavaScript-specific). If you deliberately have chosen the same property name, you can access the inherited value by manually ascending the prototype chain with Object.getPrototypeOf().
[1]: Speaking of both attributes and methods, as they're just properties in javascript
You could give one of your constructors a base property, which will get the properties from the inherited constructor:
function SynthOne() { // constructor 1
this.base = {};
this.sound = "piano";
SynthTwo.call(this.base);
};
function SynthTwo() { // constructor 2
this.sound = "bass";
}
SynthOne.prototype = Object.create(SynthTwo.prototype);
var synthsCombined = new SynthOne;
console.log(synthsCombined.sound); //piano
console.log(synthsCombined.base.sound); //bass
But from what it looks like you are trying to accomplish, maybe inheritance is not the right way for you. It might make more sense to create a generic Synth class and maybe a SynthCollection class, to combine different Synths.

How to introduce the prototype pattern to javascript namespace

Before I begin, I want to confess that I am a JavaScript novice and I have very little understanding/knowledge of JavaScript patterns and terminologies so please feel free to explain basic concepts to me like I'm 5!
I have previously used the JavaScript prototype pattern to great effect in my work.
Here is a sample of my previous work with the prototype pattern
var SomeNameSpace = SomeNameSpace || {};
SomeNameSpace.SomeClass = function(oSomeParameter){
this.SomeProperty = oSomeParameter
...
}
SomeNameSpace.SomeClass.prototype = {
SomeClassMethod: function (oSomeOtherParameter) {//code here}
}
var someClassInstance = new SomeNameSpace.SomeClass("some string");
var result = someClassInstance.SomeClassMethod("some other string");
That snippet is an example of how I have always worked with javascript
I have been put in charge of supporting some new javascript code. I would like to introduce the same sort of prototype pattern to this new library. However, the namespace is written in a way which is foreign to me and I do not know how to modify it to suit my needs.
An example
if (typeof SomeNamespace == "undefined") {
SomeNamespace = { __namespace: true };
}
SomeNamespace.SomeOtherNamespace = {
SomeClass: function(oSomeParameter){
this.SomeProperty = oSomeParameter
...
}
}
I don't know how to add prototype functions to this code....
(Sorry if I'm vague on details, I'm not even sure why the namespace is declared like that in my 2nd example so if someone could explain that to me, that'd be great!)
*Edit*
Corrected syntax in 2nd example
*Edit*
Left out the "new" keyword in my example
Defining methods
This piece of code is not syntactically correct:
SomeNamespace.SomeOtherNamespace = {
SomeClass = function(oSomeParameter){ // you probably have : instead of =
this.SomeProperty = oSomeParameter
...
}
}
To add an instance method in the second example, you can simply do after the definition of SomeClass:
SomeNamespace.SomeotherNamespace.SomeClass.prototype.SomeClassMethod = function() {
};
In both the first and the second way you mentioned, your code wants to show that these functions (instance methods in first example, classes in second example) all belong to the same object (prototype in first example, namespace in second example). That is all nice and good for a few properties, but i find this gets more in the way when you're dealing with classes with many methods or even worse, namespaces with many classes.
I would recomend you separate your code using different files and minify them together. A folder represents a namespace and a file represents a class. Follow the pattern in your first example, but instead of saying "this is the prototype object with these methods", simply add them one at a time using the example line above.
Declaring namespaces
First of all, we need to be on the same page. In JavaScript a namespace is simply an object (that contains as properties whatever interests you, constructors, static functions - ex factory methods, other namespaces, etc).
The first example a = a || {} makes sure that namespace a is defined but makes sure not to overwrite it if it was defined elsewhere. For most use cases it is enough and it has the advantage of being very concise and clear to most people reading your code.
The second example does something similar to what the first does, but with two differences:
Specifically checks that a was undefined before defining it (ex1 only checked for falsyness which is usually enough)
Adds the _namespace property to a
Regarding the check for undefined, i doubt you need it. If your code has collisions with something that uses 'a' as something else than an object, then there's a high chance something will break regardless of the method used.
The _namespace property is something purely conventional to that code i think. It may help with various tools (perhaps during debugging or for automatic documentation generation), but that's about all i can think of. Obviously you're in a much better position to see if it is actually used for something, so if you encounter an interesting usage, perhaps you could leave a comment.
To sum it up, i prefer the first variant because it is more concise and even more frequent (so easier to recognize by someone reading the code).
Full example:
// class definition
a = a || {}; // global namespace, all good
a.b = a.b || {}; // both lines are needed
a.b.Class = function() {
this.myProp = 'hello';
};
a.b.Class.prototype.myMethod = function() {
};
// usage
var myInstance = new a.b.Class();
instance.myMethod();
var x = instance.myProp;

this in javascript not populating data as expected

My code -
<script type="application/javascript">
var firstObject = {
sayHello : function(){
document.write("My name is "+ this.myName +"<br>");
},
myName : "Swapnesh Sinha"
};
var secondObject = {myName : "Sanjay Sinha"};
document.write("First one " + firstObject.sayHello() );
document.write("<br>");
document.write("Second one "+ secondObject.myName);
</script>
Source - http://learn.jquery.com/javascript-101/this-keyword/
Expecting output -
First one Swapnesh Sinha
Second one Sanjay Sinha
Unexpected Output (from my sense)-
My name is Swapnesh Sinha
First one undefined
Second one Sanjay Sinha
Let me know the case why it returns undefined however source is mentioning to return name ? or something I am getting wrong from my side
In your first document.write, you call a function, and ask the return value of the function to be concatenated to the string "First one ".
The function is evaluated, at which point "My name is Swapnesh Sinha" gets outputed via document.write call inside the object. That function call however does not return a value, hence it is undefined, and that gets concatenated to "First one", which is then printed.
Here is the working fiddle: JsFIDDLE
Here is what you fail to understand, as most jQuery developers: JavaScript scoping.
Basically, in order for a property to be accessed via this, it has to be nested in the Object.prototype.
Correction
When you define the object properties inline, calling this will still point to the right object. However, the pattern I gave you, even though less popular, is a much neater and better approach.
The prototype is the JavaScript way of OOP. If you are looking for solid OOP style JS and for proper definition of models, improved code maintainability and better coding style, it is preferred to define classes using the pattern I gave you, as it will allow you to make a strong distinction between static functions and classes. It is also the natural flow of JavaScript, where everything is an object.
In high level JavaScript programming(powerful Ajax applications or applications where for one reason or the other the browser has to perform more advanced computation), the below style is always preferred. Static functions placed under a namespace are still defined separately:
var namespace = {};
namespace.firstStaticFunc = function() {/*do stuff etc;*/};
namespace.secondStaticFunc = function() { return !1; };
The only reason why you use your definition pattern is enums and hash maps. For instance:
var typesOfChicken = {
RED: 'red',
BLUE: 'blue'
};
The above is always used for things like internationalization and avoidance of hard coded values. Also, it helps JS minifiers to a better job. Given the above, you can say:
console.log(typesOfChicken.RED);// will print red.
console.log("red");// wil still print red
But, when I want to change red to something else, using enums I only have to do a single change. Also, the minifier can replace typesOfChicken.RED with a.b, whereas "RED" will always be "RED". It's unminifiable.
var firstObject = function() { };
firstObject.prototype.myName = "Swapnesh Sinha";//this will not be nested as an instance property.
firstObject.prototype.sayHello = function() {
alert(this.myName);// will now correctly display Swapnesh Sinha
};
// to use your first object.
var instance = new firstObject();
instance.sayHello();
To properly make use of scope, use the pattern I gave you, which is an Object Oriented pattern and the right approach to defining classes in JS.
And now you have a great way to organize your JavaScript code, it's fair easier to maintain, scope is a lot more obvious and most important of all you can immediately make a distinction between static functions and classes.
replace document.write() with return in your sayHello function

Can you extend an object that has access to private properties with a function that can also access those private properties?

I am creating an object inside of an enclosure. Also in the enclosure are private properties that the object's functions can access - and this works as expected.
My issue: I want others to be able to extend my object with functions of their own (functions from a different context), but those functions will also need access to the same private properties - and I have not been able to find a way to make this work.
I've tried various configurations of .call, and also wrapping their function in a new function, amongst other things. I feel like I've gotten close to a solution, but have just fallen short.
Here's a bit of simplified example code that accurately reflects my situation:
//extension object
//fn2 can be any function, with any number of arguments, etc.
var obj1 = {};
obj1.fn2 = function (s1, s2){ console.log(priv); };
//actual object
var obj2 = (function (){
//private property
var priv = "hello world";
//return object
var obj3 = {};
//return object's native fn (works)
obj3.fn = function (s){ console.log(priv); };
//extension happens here - but is obviously not correct
obj3.fn2 = obj1.fn2;
//return object
return obj3;
})();
//try output
obj2.fn("goodbye world"); //works
obj2.fn2("goodbye world", "thx 4 teh phish"); //fails
Any insight would be appreciated. And I totally understand if what I want just isn't possible - but it sure seems like it should be :P
EDIT: Thank you all for the responses. I fully understand that the properties are more easily accessed as public, and that normally inherited objects won't have access to them otherwise. However, since the new function is being attached to the original object I have to believe there's a way to use the original context and not the context the new function was created in.
Now, I'm the first to say that eval is evil - and, in fact, I've never used it, or even considered using it, before. However, I'm trying everything I can think of to make this work - and I stumbled across this (seemingly) working solution:
obj3.fn2 = eval(obj1.fn2.toString());
So, if I check to make sure that obj1.fn2 is a typeof function, is there any way this could be harmful to my code? It doesn't execute the function, so I can't see how - but maybe I'm missing something?
Javascript doesn't have a "protected" analog. You either get super private or completely public. From here you can choose to:
Reconsider your class design, and have the subclasses depend only on the public interface of the parent class.
Add getter and setter functions to the public interface. Not necessarily the best thing though as you might just as well make the properties public (besides best practice issues and whatnot)
Just use public properties instead. This is the "natural" way to do OO inheritance in Javascript and is usually not a problem if you use a donvention like adding an underscore to the beggining of the name. As a bonus you can use the prototypal inheritance feature (it is nice knowing how to use this instead of only closure-based classes)
function Base(){
this._priv = "Hello world"
};
Base.prototype = {
fn: function(){
console.log(this._priv);
}
}
var obj2 = new Base();
obj2.fn = function(){ ... }
I hate to answer my own question - seems like a bit of a faux pas - but c'est la vie. (because I woke up French today?)
So, while I found that the eval() solution I presented last night in the edit to my original question does seem to be a valid solution, and a proper use of eval for retaining the object's context within the new function, it is far from perfect.
Firstly, it works in FF, but both IE and Chrome seem to hate it (those were the next ones I tried, and I quit trying others after they both failed). Though I'm sure it could probably be made to work across browsers, it seems like a hassle.
Secondly, it does give quite a bit of power to the new function, and as I look at my code more I do like the idea of controlling exactly what these new functions being added to my object get access to.
Thirdly, .eval() is typically pretty slow - and it turns out that .apply() (which is typically faster) just may work well enough.
This is because I realized at some point last night that no new functions on this object will need to set any of the private variables (at least, I'm fairly certain they won't) - and .apply() works fine to pass the values through for them to read.
I'm sure there's more to it than just those 3 things, but for now I think I'm going to go with more of a 'wrapper' solution - something like this:
var f = function (){
var fauxThis = {};
fauxThis.priv = priv;
obj1.fn2.apply(fauxThis, arguments);
};
obj3.fn2 = f;
//(To be placed where I had "obj3.fn2 = obj1.fn2;")
I am certainly willing now to consider the use of eval() in very specific cases - and may even revisit this specific use of it before I make my final decision of which direction to take. (especially if I can think of a case where the private value would need to be set)
Thanks all for your input!
The quickest and easiest solution is to prefix any supposedly private properties with the underscore (_).
Personally I like to bottle my private properties into a single object which would be placed on the object, like so:
obj.publicProp = 20;
obj._.privateProp = true;
I wouldn't worry so much about it though, the underscore is basically a universal symbol for private so those using the script will know that it's private and shouldn't be touched. Or, better yet, just leave it out of the public documentation ;)
There are other methods and you can use which do emulate "true" protected variables, but they're not the best as they avoid garbage collection, and can be clunky to use.

Encapsulation in Javascript

I'm pretty new to Javascript, as my SO profile will attest.
I've just been reading up on a few tutorials and come across something I don't totally understand in regards to Object Orientation and Encapsulation when applied with Javascript.
The tutorial stated that Javascript objects can be declared like this:
var myCustomObject = new Object();
And that you can give it instance variables like this:
myCustomObject.myVariable = "some value";
myCustomObject.myOtherVariable = "deadbeef";
Finally, it states that you can create a template function to create new objects like this:
function CustomObject(myVariable, myOtherVariable)
{
this.myVariable = myVariable;
this.myOtherVariable = myOtherVariable;
}
I also know that you can create and assign values to variables that do not yet exist and as a result are declared implicitly, as is seen in the example, where myCustomObject didn't have a myVariable, but now it does.
So, my question is: What is there to prevent new variables from being added at some other point in the code. If I'm trying to learn how an object works and what I can/should do with it, I may never see the variable additions that could well be in some other .js file, and thus not have a full understanding of the object...
Also, how do I know that some object that has just been created won't suddently turn out to have 60 more variables added later on in code that weren't mentioned at all at creation time?
How are you meant to be able to understand what an object can contain at a glance if more can just be added to it "willy nilly"?
I can't quite believe that I'm about to quote Spiderman but …
With great power comes great responsibility
JavaScript is powerful and flexible and gives programmers lots of freedom. It doesn't come with features designed to stop programmers writing bad code. When you write JavaScript, you are responsible for making sure the code is good, not the language.
You can't, there's nothing that stops me from doing whatever I want with your objects ;) However, you don't have to use those variables..
One thing you can do is to play with scopes, example:
function myConstructor()
{
var myState = {}; //Create new, empty object
myState.text = "Hello World!";
this.say = function() {
alert(myState.text);
};
}
In this simple example you can store you internal variables in myState (or "var text = '';" etc) and they aren't accessible from outside since they are not members of an object, they are just private variables in your function. And, as you can see, the function say still has access to it.
Short answer: Absolutely nothing.
Long answer:
Javascript is a dynamic language in more ways than just the type system. Every object like thing in the language is basically an associative array which can be added to as you please. Variables (which can obviously contain these object like things) exist only within their function scope.
You can use this point to simulate private members which can tame the situation somewhat. I've posted examples of this several times before so I'll just refer you to the definitive guide on the subject: http://javascript.crockford.com/private.html.
As far as adding new members to objects in a way you did not intend goes, there's really nothing to be done that's just the way the language is.
Afterthought:
When approaching javascript try to remember it's really not an OOP language it's a weird and wonderful mix of functional / prototypical with a few OOP ideas. Don't be fooled by the java like syntax, you'll have a much better time if you play to the languages strengths rather than ape java.
Javascript objects are transformers (TM), they can turn from one form to another.
In practise this only happens to enrich objects, never to cause harm. It allows one to for example upgrade an existing 'class' rather then subclassing or to decorate instances again removing the need to create even more 'classes'. Take the following example:
var Vehicle = function(){}
var factory = {
create: function(name, props){
var v = new Vehicle();
v.type = name;
for(var prop in props) {
v[prop] = props[prop];
}
}
}
var bike = factory.create('Bike', {
wheels: 2
});
var car = factory.create('Car', {
wheels: 4,
doors: 5,
gear: 'automatic'
});
var plane = factory.create('Airplane', {
wings: 2,
engines: 4
});
Imagine what the code above would take without dynamic objects and you couldn't do this:
// lets paint our car
car.color = 'candy red';
// bling!
car.racingStripes = true;
car.mirrorDice = true;
car.furryChairs = true;
You get to enrich/personalize objects in a much easier way.

Categories

Resources