JavaScript getter and setter - javascript

This is such a fundamental question, that I'm sure it's a duplicate, so I apologize in advance, but is this how I write an object such that I use by saying:
myApplication.myFirstMethod(x);
x = myApplication.myFirstMethod();
Here's the code:
myApplication = {};
(function() {
myApplication.myFirstMethod = function() {
var local = {};
if (arguments.length) {
local.result = arguments[0];
}
return local.result;
}
myApplication.mySecondMethod = function() {
var local = {};
if (arguments.length) {
local.result = arguments[0];
}
return local.result;
}
})();

jsFiddle Demo
A more object oriented approach would be to use instantiation and prototype.
Setup
var Application = function(){
this.local = {};
};
Application.prototype.Value = function(){
if (arguments.length) {
this.local.result = arguments[0];
}else{
return this.local.result;
}
};
Used
var app = new Application();
app.Value(6);
alert(app.Value());//6
From a jQuery point of view, they will first screen to see if there are arguments, this code is direct from their source for the val function:
val: function( value ) {
if ( !arguments.length ) {
var elem = this[0];
...
It then goes on to use the element's native API and some other metrics to get the value for the element (In general, the only type of elements which will return a value from val are going to be elements such as input, select, etc. - form elements basically).
At the end of the if block it attempts to return various results based on if it found a value attached to the element (or set of elements). This guarantees that the clause of "setting" never executes when a "get" is encountered. If the case is that "set" is being used it goes through a slightly complex set of code to properly set a value to the element.
The reason that the code shows val: function() is because it is part of an object which is being used to "extend" the jQuery prototype using jQuery's extend functionality.
This is the exact code in a jsfiddle of jQuery's val function

There are many patterns for creating objects like this and everyone has their favorites. Addy Osmani does an excellent job of summarizing the most popular patterns in his Javascript Design Patterns "book". Specifically, this section:
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#designpatternsjavascript
I reread this semi-annualy just to make sure I'm keeping all the patterns in my quiver.

Related

Function scope in JavaScript. Different objects same result

My question is based on the following scenario.
var test = (function(){
var SlideManager = !function(){
this.Sequencer = {
getSequence : function()...
}
return this;
}()
var LayerManager = !function(){
this.Sequencer = {
getSequence : function()...
}
}()
var module = {};
module.foo = function(){}
return module;
})()
As an explanation, the test object has two helper objects in its scope: SlideManager & LayerManager. These two handle different actions for the entities slide && layer. Each entity has its own fixed position in the DOM, position which should be retrieved through the Sequencer helper object.
Please note that every Manager should have its own Sequencer and I would expect that to be true in the provided example.
However it seems that there is a problem with my understanding of js scopes because both Managers have the same Sequencer (The one from Layer Manager).
Should I expect something like this or am I doing something wrong somewhere else in the code.
Thank you!
To expound upon what Scott Hunter said...
Just auto executing the functions (function() {})() Does not give them a new scope. For that you are wanting the "new" keyword.
So:
var SlideManager = function(){
this.Sequencer = {
getSequence : function()...
}
return this;
};
var LayerManager = function(){
this.Sequencer = {
getSequence : function()...
}
};
var slideManagerInstance = new SlideManage();
var layerManagerInstance = new LayerManager();
Might be more what you are looking for... also why are you "!" banging the auto executed functions return before assigning... that will give you a true/false boolean?
this in both Managers isn't local to that function, and thus is the SAME in both, which is why they have the same Sqeuencer.

Should I use memoization or object's cache

I'm reading memoization chapter of John Resig's book about Javascript and I've got the following question:
Is it better to develop memoization for a method or create cache as object's property assuming that I can modify object's design?
This example implements caching as part of object's functionality:
function Calc() {
this._cache = {};
this.isEven = function(arg) {
return this._cache[arg] !== undefined ?
this._cache[arg] :
this._cache[arg] = (arg%2===0);
}
}
This example implements caching as part of function's functionality:
function Calc() {
this.isEven = function(arg) {
this.isEven.cache = this.isEven.cache || {};
return this.isEven.cache[arg] !== undefined ?
this.isEven.cache[arg] :
this.isEven.cache[arg] = (arg%2===0);
}
}
This is the way they should be used:
var obj = new Calc();
obj.isEven(3);
Well, here's the thing: what if you had an "isOdd" function? You would want it to have its own cache, so the second option is easier.
That being said, this isn't really a good example, because x%2==0 is a really cheap operation, so it shouldn't be made into a function.

Understanding Classes and Inheritance in Javascript - New Pattern

I'm designing an OOP inheritance pattern for many applications I'm building. Javascript has many ways of doing this, but I stumbled on a pattern I really like. But now I'm struggling with the need for a separation of classes and instances.
I have a base object called Root. And it has a main method called inherit. To create a new object you use
var Person = Root.inherit({
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
Then to create an "instance" you would
var sally = Person.inherit({
name : "sally",
height : "5'6"
});
sally can .talk() and she can walk() and she has a .name and a .height
You can make more people the same way.
If you want a constructor you use
var Person = Root.inherit({
_construct : function() {
// do things when this object is inherited from
},
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
It also has the ability to have init, when the object is first defined in code (singletons use this)
var Person = Root.inherit({
_init : function() {
// called at runtime, NOT called if an object is inherited from me
},
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
So as you can see, everything uses .inhert(). There are no classes and no instances really. Everything is an instance of something. The only real problem I found so far is that there is no concept of "type", but you can always just check for a method if you need to. Also you can't protect a 'class', as a 'class' can be changed during execution if the developer accidentally changed it, or meant to change it.
So my question is: Is there a need in javascript to have an explicitly and controlled separation of class structure and instances of the class? Are there any issues with treating every object as an instance?
No there's no need since Javascript is a Prototypal based language, meaning that classes are not involved. You are just creating clones of the objects.
http://en.wikipedia.org/wiki/Prototype-based_programming
As far as the concept of type, the type is object.
A good read for more info about this would be Javascript Patterns by Stoyan Stefanov he has several different creational patterns that address your concerns, including examples that implement Design Patterns from the gang of four's design patterns.
http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752
So my question is: Is there a need in javascript to have an explicitly and controlled separation of class structure and instances of the class? Are there any issues with treating every object as an instance?
Not really, if you're happy with it, it's fine.
The more normal form of JavaScript inheritance does much the same thing. You'll frequently see structures like this (severely cut down for brevity):
function Base() {
}
Base.prototype.foo = function() {
};
function Derived() {
}
Derived.prototype = new Base();
...and of course, new Base() is also how you create instances of Base. So your system is quite similar.
Again, the above is a sketch, not a full example. For one thing, usually you'd see construction and initialization separated out, so you don't literally see Derived.prototype = new Base() so much as something that creates an object with Base's prototype but without actually calling Base (which Derived would do later), but you get the idea. Granted that statement somewhat weakens the similarity with your system, but I don't think it breaks it at all.
At the end of the day, it's all about objects (instances), which are either used directly (your sally) or indirectly by providing features to other objects (Person, Root) by cloning or by setting them up as the prototype of the other object.
Javascript's inheritance is prototypical which means everything object is an instance. You actually have to do extra work to get the classical inheritance.
This is how I work in javascript
// this is class
function person(){
// data is member variable
this.name = null;
this.id = null;
//member functions
this.set_name = _set_name;
this.get_name = _get_name;
this.set_id = _set_id;
this.get_id = _get_id;
function _set_name(name){
this.name = name;
}
function _get_name(name){
return this.name;
}
function _set_id(id){
this.id = id;
}
function _get_id(id){
return this.id;
}
}
// this is instance
var yogs = new person();
yogs.set_id(13);
yogs.set_name("yogs");
hope it may help
Start with some basic object...
// javascript prototypes - callback example - javascript objects
function myDummyObject () {
that = this;
} // end function myDummyObject ()
// begin dummy object's prototype
myDummyObject.prototype = {
that : this,
// add a simple command to our dummy object and load it with a callback entry
say : function () {
var that = this;
console.log('speaking:');
that.cb.run("doSay");
}
} // end myDummyObject proto
extend with a sub prototype..
// here we addon the callback handler... universally self sufficient object
var cb = {
that : this, // come to papa ( a link to parent object [ myDummyObject ] )
jCallback : new Array(new Array()), // initialize a javascript 2d array
jCallbackID : -1, // stores the last callback id
add: function(targetFnc, newFunc) {
var that = this;
var whichID = that.jCallbackID++;
// target, addon, active
that.jCallback[that.jCallback.length] = { 'targetFunc' : targetFnc, 'newFunc' : newFunc, 'active' : true, 'id': whichID };
return whichID; // if we want to delete this later...
}, // end add
run: function(targetFnc) {
var that = this;
for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
if( that.jCallback[i]['targetFunc'] == targetFnc && that.jCallback[i]['active'] == true )
that.jCallback[i]['newFunc'](); // run callback.
}, // end run
remove: function (whichID) {
var that = this;
console.log('removing:' + whichID);
for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
if( that.jCallback[i]['id'] == whichID )
that.jCallback[i]['newFunc'](); // run callback.
} // end remove
}
// add the object to the dummy object...
myDummyObject.prototype.cb = cb;
Example:
var testing = new myDummyObject();
testing.cb.add('doSay', function () { console.log('test: 213123123'); } );
// test remove...
var testid = testing.cb.add('doSay', function () { console.log('test: 12sad31'); } );
testing.cb.remove(testid);
testing.cb.add('doSay', function () { console.log('test: asdascccc'); } );
testing.cb.add('doSay', function () { console.log('test: qweqwe'); } );
testing.cb.add('doSay', function () { console.log('test: d121d21'); } );
testing.cb.add('doSay', function () { console.log('test: wwww'); } );
testing.say();
This always seemed the easiest for me to understand... Just create a new instance of the inherited class and then loop through its variables and methods and add them to the main one.
var myPerson = new Person()
var myPerson.firstName = 'john';
var myPerson.lastName = 'smith';
var myPerson.jobTitle = 'Programmer';
var Person = function(){
//Use this to inherit classes
this._extendedClass = new Person_Job();
for(var i in this._extendedClass){
this[i] = this._extendedClass[i];
}
delete this._extendedClass;
this.firstName = '';
this.lastName = '';
}
var Person_Job = function() {
this.jobTitle = '';
}

Javascript apply — Inheriting classes

The code below is adapted from this answer
function MessageClass() {
var self = this;
this.clickHander = function(e) { self.someoneClickedMe = true; };
var _private = 0;
this.getPrivate = function() { return _private; };
this.setPrivate = function(val) { _private = val; };
}
ErrorMessageClass.prototype = new MessageClass();
function ErrorMessageClass() {
MessageClass.apply(this, arguments);
}
var errorA = new ErrorMessageClass();
var errorB = new ErrorMessageClass();
errorA.setPrivate('A');
errorB.setPrivate('B');
console.log(errorA.getPrivate());
console.log(errorB.getPrivate());
The original post did not have the MessageClass.apply(this, arguments); since the purpose was to show how inheritance can go wrong in Javascript.
My question is, is saying: ErrorMessageClass.prototype = new MessageClass(); before the ErrorMessageClass constructor has even been declared bad practice? My understanding is that calling undeclared identifiers like that causes a silent declaration to occur, with the result being placed on the global window object, which I understand is bad.
Is this form:
function ErrorMessageClass() {
MessageClass.apply(this, arguments);
}
ErrorMessageClass.prototype = new MessageClass();
considered to be better practice? This link shows the code written as it was originally above, which is why I even tried it. Does this blogger know something I don't (quite likely)?
EDIT
Lots of great info in the answers below, but I did want to highlight this link which really explains things perfectly
Usually, to avoid this confusion, you would just attach the prototype after, but as Adam Rackis pointed out, function declarations are hoisted, like var statements.
However, you should not instantiate the base object as the prototype. If your base object takes arguments, what are you supposed to use? Use an empty "surrogate" constructor
// Used to setup inheritance
function surrogate () {};
function MessageClass() {
var self = this;
this.clickHander = function(e) { self.someoneClickedMe = true; };
var _private = 0;
this.getPrivate = function() { return _private; };
this.setPrivate = function(val) { _private = val; };
}
// The key steps to creating clean inheritance
surrogate.prototype = MessageClass;
// Sets up inheritance without instantiating a base class object
ErrorMessageClass.prototype = new surrogate();
// Fix the constructor property
ErrorMessageClass.prototype.constructor = ErrorMessageClass
function ErrorMessageClass() {
MessageClass.apply(this, arguments);
}
There's much more to be said. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
It works because function declarations are evaluated first. If you tried to move these classes under an object literal "namespace" the first version would fail.
I personally find the second method to be much easier to read - also, don't forget to set the sub-class' prototype.constructor property back to itself. Personally, I use an inherits() method on the Function prototype which wraps up essentially the type of code you're using here.

Javascript OOP best practices? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I'm sick of seeing dozens of different ways of doing object oriented programming in Javascript. Can anyone just tell me which technique I should use considering I want to work on a large scale project and I want my code to be future proof?
These are just a few quick guidelines I've come up with, if anyone else has anything meaningful to add, I've set this answer as a community wiki so it should be easy enough for you to edit.
Namespace your objects to ensure they will never conflict with third party JavaScript libraries.
window['Andrew']['JS'] = {
addEvent: function(el,evName) {/*Stuff*/},
Rectangle: function(width,height) {/*Stuff*/}
};
So then you would create a rectangle object by using:
var myRect = new Andrew.JS.Rectangle(14,11);
And then your code will never interfere with, or be interfered by anybody else's Rectangle.
Use a consistent naming strategy, specifically:
Object names should be capitalized, everything else (variables, functions) should begin with a lower case character i.e.
var myRect = new Andrew.JS.Rectangle(14,11);
document.write(myRect.getArea());
Ensure everything is meaningful, i.e. verbs for methods, nouns + adjectives for parameters.
Make sure all methods and parameters are relevant to the object they belong to. e.g.
In this example, the area of the rectangle can be converted to square feet using the method inSquareFeet().
myRect.getAreaObject().inSquareFeet();
Make sure inSquareFeet is a method of the object returned by getAreaObject() and not a method of Andrew.JS.Rectangle
Use constructors, or more specifically, try as hard as possible to make sure that an object doesn't need any further initialization to be used once it has been constructed, so instead of:
var Person = function()
{
this.name = "";
this.sayHello = function ()
{
alert(this.name + " says 'Hello!'");
return this;
}
}
var bob = new Person();
bob.name = "Bob Poulton";
bob.sayHello();
try:
var Person = function(name)
{
this.name = name;
this.sayHello = function ()
{
alert(this.name + " says 'Hello!'");
return this;
}
}
var bob = new Person("Bob Poulton");
bob.sayHello();
I always use John resig's:
http://ejohn.org/blog/simple-javascript-inheritance/
It's simple and doesn't require any frameworks to function.
Because you are working on a large scale project i would suggestion a javascript framework like mootools http://mootools.net/.
It has a good class and inheritance structure.
My ideal Object for OOP is like using an Instance method with prototypes:
Example:
var Users = function()
{
var _instance;
this.prototype.getUsername = function(){/*...*/}
this.prototype.getFirstname = function(){/*...*/}
this.prototype.getSecurityHash = function(){/*...*/}
/*...*/
/*Static Methods as such*/
return { /*Return a small Object*/
GetInstance : function()
{
if(_instance == null)
{
_instnance = new Users(arguments);
}
return _instnance; //Return the object
},
New: function()
{
_instnance = null; //unset It
return this.GetInstnace(arguments);
}
}
}
Then I would always use like:
Firstname = Users.GetInstance('Robert','Pitt').getFirstname();
Username = Users.GetInstance().getUsername(); //Returns the above object.
Me = Users.New('Robert',null); //Deletes the above object and creates a new instance.
Father = Users.New('Peter','Piper'); //New Object
Me.AddFather(Father); //Me Object.
And that's the kind of road i go down when it comes to building a JavaScript OO Style architecture.
just for your information, i think YUI provides few great tutorials on this topic
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
GlobalObject.Functionality = {};
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
Events.Init = function()
{
///<summary></summary>
}
// public method
Events.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
// Reusable "class" object
var oMultiInstanceClass = function()
{
// Memeber Variables again
var oMember = null; //
// Public method
this.Init = function(oParam)
{
oMember = oParam;
for ( n = 1; i < oMemeber.length; i += 1 )
{
new this.SubClass.Init(oMember[i]); // you get the point, yeah?
}
}
this.Subclass = function()
{
this.Init = function() { }
}
}
The strength to this is that it initializes the Global object automatically, allows you to maintain the integrity of your code, and organizes each piece of functionality into a specific grouping by your definition.
This structure is solid, presenting all of the basic syntactical things you would expect from OOP without the key words.
There are even some ingenious ways to set up interfaces as well. If you choose to go that far, a simple search will give you some good tutorials and tips.
Even setting up intellisense is possible with javascript and visual studio, and then defining each piece and referencing them makes writing javascript cleaner and more manageable.
Using these three methods as needed by your situation helps keep the global namespace clean, keep your code organized and maintains separation of concerns for each object.. if used correctly. Remember, Object Oriented Design is of no use if you don't utilize the logic behind using objects!
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
return {
publicMethod: function() { alert(iAmAPrivateVariable); },
publicVariable: bar()
}
}
//usage
var thing = foo()
This is a functional approach, and has a great deal more going for it (such as encapsulation) then anything else you are going to see
In a general way, you shouldn't be doing OO in javascript, it isn't that great a language for it for a great many reasons. Think scheme with squiggly brackets and semi-colons, and you will start writing the language like the pros do. That being said, sometime OO is a better fit. In those cases, the above is typically the best bet
to bring inheritance into the mix
function parent() {
return { parentVariable: 2 };
}
function foo() {
var bar = function() { console.log("i'm a private method"); return 1; };
var iAmAPrivateVariable = 1;
me = parent();
me.publicMethod = function() { alert(iAmAPrivateVariable); };
me.publicVariable = bar();
return me;
}
This makes things a tad more complected, but accomplishes the desired end result while still taking a functional approach to OO concepts (in this case, using decorator functions instead of real inheritance). What I like about the whole approach is we are still really treating objects the way they are intended to be in this kind of language -- a property bag you can attach stuff to at will.
Another note is this is wildly different then what you will see most of the time in most of the jobs you will ever work at, and often is very hard to explain a) what is going on, and b) why it is a good idea to coworkers.
I use such a pattern and recommend to you to use it too:
function Person(firstname, lastname, age)
{
var self = this;
var _ = {};
// Private members.
var firstname = firstname;
var lastname = lastname;
var age = age || 'unknown';
// Private methods.
function first_letter_to_uppercase(str) {
return str.charAt(0).toUpperCase() + str.substr(1);
}
// Public members and methods.
_.get_age = function()
{
return age;
}
_.get_name = function()
{
return first_letter_to_uppercase(firstname) + ' ' +
first_letter_to_uppercase(lastname);
}
return _;
}
var p = new Person('vasya', 'pupkin', 23);
alert("It's " + p.get_name() + ', he is ' + p.get_age() + ' years old.')
You can try with a simple, usefull and quick object:
var foo = {
foo1: null,
foo2: true,
foo3: 24,
foo4: new Array(),
nameOfFunction1: function(){
alert("foo1");
},
nameOfFunction2: function(){
alert("foo2");
},
}
To use this, you have to create an instance of this object and use like a object in java:
foo.nameOfFunction2();
Also you can check this link to other solution: http://www.javascriptkit.com/javatutors/oopjs.shtml
I hope that answer your question.

Categories

Resources