Javascript caching property values into the variables - javascript

I've a simple read-only JSON object with a few propeties, I wonder if it's worth caching its properties into the variables? Currently we use them like: jsonObject.somePropety ,I'm considering caching them into the variables like: var somePropertyValue = jsonObject.somePropety; and using that var for all future refs.

Depends on how you judge "worth" on this issue.
Caching the properties should have some theoretical performance gain if using the same property repeatedly, but I doubt that the difference will be noticeable to the user unless you're looping many thousands of times.
Caching the properties can make your code prettier though, e.g., if you are referring to the same property more than a couple of times in a particular block of code you could cache it at the beginning - especially if you've got nested objects like this:
jsonObject.nestedObject.doSomething();
jsonObject.nestedObject.doAnotherThing();
alert(jsonObject.nestedObject.someProperty);
//compared with:
var nObj = jsonObject.nestedObject;
nObj.doSomething();
nObj.doAnotherThing();
alert(nObj);
I find the latter easier to type and easier to read (at least, it would be easier to read if the variable nObj had a more meaningful name, but obviously this is just a generic example).
I would not, however, cache the properties in global variables for use throughout all of your code. Keeping globals to a minimum is almost always a good idea for several reasons, including avoiding clashes in naming with included libraries, and avoiding hard-to-diagnose bugs where multiple functions update the same variable. Just cache within individual functions that happen to need to use a particular property a lot - and remember that JS has function scope not block scope. (Where a particular function references a particular property a lot you could also consider making that property an argument to the function for the same effect with (arguably) neater code.)
P.S. JavaScript doesn't have JSON objects, it just has objects.

It really depends on where jsonObject is stored, and how many scope steps (function closures) away from where it's being used it is.
e.g. in the example below each time jsonObject.prop is accessed the code checks the scoped variables of 6 different scopes (including the global scope) before it finds jsonObject
var jsonObject = { ... };
(function() {
(function() {
(function() {
(function() {
(function() {
jsonObject.prop ...;
jsonObject.prop ...;
})();
})();
})();
})();
})();
So if the property is being accessed multiple times in the innermost function it makes sense to save a local reference to it
var jsonObject = { ... };
(function() {
(function() {
(function() {
(function() {
(function() {
var prop = jsonObject.prop;
})();
})();
})();
})();
})();
Now (apart from the first time the property is accessed to write it to the variable) your code has to do a lot less work to find the value.

Related

Storing document and window references in an object to get better performance

I have one question and don't know do I do right thing.
I define window and document in objects or global variable in my pluins like this:
var myplugin = {
document : document || {},
window : window || {}
};
After I call that when I need like this:
myplugin.window.location.href = 'http://flyflyflymachine.etc';
And I would like to know do I get some better performance or is unnecessarily?
As for performance, yes caching can help but you are not caching anything here. Merely replacing one lookup with another one (yourplugin.document vs window.document).
Actually in that case, just document is faster, but unless you are in a tight loop calling it a few thousand times, don't bother with these kind of nano optimisations.
In theory this kind of nano-optimization is more appplicable to nested functions created when a plugin is defined in terms of an IIFE instead of using an object literal initializer.
When code references a variable of object, the javascript engine has to search the current lexical scope record first, followed by any parent lexical scrope records until the variable or object definition is either found or proven not to have been defined.
Lexical scope records are created for for loops using let variable definitions and for functions to hold arguments and variables. So in a deeply nested for loop, in a deeply nested function, there could be a number of scope records to inspect before finding either window or document.
Making a copy of a global or outer function reference could reduce the number of scope records to search. A net performance gain will only arise if the overhead of making the copy is less than the overhead of the JavaSript engine searching the intermediary scope records, multiplied by the number of times the outer reference is used. This may be both rare in practice and difficult to prove if the gain is small.
The kind of plugin definition in the post, consisting of an "Object object" intializer instead of an IIFE does not meet the criteria of speeding up object reference searching and, indeed, could actually slow things down.
You seem to be concerned about window or document not existing. If, for example, this code were run from inside a Worker or NodeJS script, it would throw an error.
So you could "optimize" this in two ways:
Use a namespace with the this keyword (from global scope, this will refer to the global object)
var myPlugin = {};
(function myPluginNS(_global) {
myPlugin.window = _global;
myPlugin.document = _global.document || {};
})(this);
Use good ol' fashioned try-catch
var myPlugin = {};
try {
myPlugin.window = window;
} catch (e) {
myPlugin.window = {};
}
try {
myPlugin.document = document;
} catch (e) {
myPlugin.document = {};
}
Admittedly, not really an "optimization", but it will at least ensure your code can run in various JS run-times.

Nesting functions in Knockout looks messy, why not use prototype key word?

How is:
var ViewModel = function() {}
var ViewModel.prototype.functionName = function() {};
different from:
var ViewModel = function() {
this.functionName = function() { ... }
}
And would the first approach be considered "wrong"? To me it seems much more readable then the second. I believe the second is the first, just with out the concept of "writing .prototype. every time"?
Any help clearing this up might make things make more sense to me.
The difference is where the function is defined.
Using the ViewModel.prototype.functionName version, the function is defined in the prototype and is available to all instances of the type without further execution cost or memory consumption.
Using this.functionName, the function is defined in the instance itself. It has the advantage of allowing every instance to have a unique version of the function, usually used to capture instance specific data.

What is difference between function FunctionName(){} and object.FunctionName = function(){}

Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:

Help understanding twitters widget.js file, a closure within a closure?

http://a2.twimg.com/a/1302724321/javascripts/widgets/widget.js?1302801865
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
Then a closure:
(function() {
...
})(); // #end application closure
Within the application closure:
TWTR.Widget = function(opts) {
this.init(opts);
};
(function() {
// Internal Namespace.
var twttr = {};
})();
Some methods are marked public, others private, and the only difference seems to be the naming convention (private starts with underscore '_').
Is it designed using the module pattern?
Why or what benefit do you get with a closure within a closure?
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
Just trying to learn from this thing!
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
That is bad coding practice, variables should always be declared with var. And there are no "namespaces" in javascript, that term is applied to the above construct but it isn't really appropriate. Better to say its methods are contained by an object.
Then a closure:
> (function() { ...
>
> })(); // #end application closure
That pattern has come to be called an immediately invoked function expression or iife. Not sure I like the name, but there you go. Anyway, it doesn't necessarily create any useful closures. A closure is only useful if a function creates variables that become bound to some other execution context that survives beyond the life of the function that created them (I hope that doesn't read like gobbledy-goop). You don't need an iife to create a closure.
However, you can use the above pattern to create closures since it's a function much like any other function.
Within the application closure:
> TWTR.Widget = function(opts) {
> this.init(opts); }; (function() {
> // Internal Namespace.
> var twttr = {}; })();
Some methods are marked public, others
private, and the only difference seems
to be the naming convention (private
starts with underscore '_').
The use of "public" and "private" are a bit misleading in javascript. The use of underscore to start identifer names indicates something that should only be used within the current scope, or by the "library" code itself. It's a bit redundant since the code should have a published API and any method that isn't part of the API shouldn't be avaialble externally.
But that is largely a matter of coding style and personal preference.
Is it designed using the module pattern?
Richard Cornford's "module pattern" is just that, a pattern. It's handy for simulating "private" variables in javascript, and also to share properties between functions or methods other than by the usual prototype inheritance. widget.js might be implemented (in parts) using the module pattern, but it it was likely designed by considering requirements and functionality. ;-)
Why or what benefit do you get with a closure within a closure?
Exactly the same benefits of any closure as stated above. Accessing variables essentially by placing them on an appropriate part of the scope chain is essentially the same as accessing properties via a [[prototype]] chain, only with (very different) mechanics - one uses identifier resolution on the scope chain, the other property resolution on the [[prototype]] chain.
Edit
One drawback is that the entire activation object that the closed variable belongs to is probably retained in memory, so if you just need access to a shared variable, better to consider some other scheme, perhaps even classic prototype inheritance. Or at least if you are going to use closures, try to keep the related activation object as small as reasonably possible (e.g. set any variables that aren't used to null just before exiting).
e.g.
var foo = (function() {
// Variables available for closure
var a, b, c;
// Use a, b, c for stuff
...
// Only want closure to c
a = null;
b = null;
return function() {
// use c
}
}());
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
I can't access the linked resource right now (corporate blocking of twitter domain), but the load order suggests you are correct. However, some code execution might be delayed until the document is fully loaded so it isn't a guaranteee, you'll need to look at the code.

Accessing variables from other functions without using global variables

I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery

Categories