Javascript global variables or object variables - javascript

I prefer to declare one Javascript file for my all website. I am trying to decrease the usage of global variables. My examples at the below, in both case each object has a myName field.
I would like to know when they are initialized?
And In terms of memory and efficiency which one is more effective?
For variable a, is declaring a.myName the same as global "var myName = Rebecca" ?
var a = {
myName : 'Rebecca' ,
sayHello : function() {
console.log(this.myName);
}
};
var b = {
myName : function() {
return 'Rebecca';
},
sayHello : function() {
console.log(this.myName());
}
};
Thanks

I believe these will be initialized identically (i.e. when the code is reached). What's different is what's happening when they are initialized and where the load is placed when their data is actually required.
To me, it would depend a lot on what you were expecting to have in myName. If it were just a string, I'd avoid the function and go with choice a. On the other hand, if there were a great deal of logic involved and that logic might not need to be invoked (for example, if it only gets executed when a user clicks on a button or the application reaches a certain state), I'd go with choice b. As I understand it, the function does consume memory and won't get garbage collected (which is a minus), but it also won't consume CPU resources until it's actually needed (which can be a huge plus).
I'm not sure I understand the question, but I'd say it's not the same. If the only member of a is myName then the two are equivalent (both are occupying the global namespace. But if you have multiple properties, the savings become obvious. From your examples, I think it's clear you understand this, so again I may not understand the question.

They will be initialized when the statements are first encountered. In a, 'Rebecca' is initialized as the value for the myName key. In b, it's just data internal to the myName (anonymous) function. a will be slightly more efficient because it avoids a function call. I also find it more readable in this simple example.
I find the choice to put everything in a single file questionable. In some cases, you want a modular design. And since you're worried about efficiency (albeit perhaps prematurely), note that having one big file can actually hurt performance if pages include code they don't need.

1) They are initialized when the script is processed in the browser, unless you declare the objects in an event handler. In that case the object is created when the event script is executed.
2) In terms of efficiency, a will probably be more efficient. Note though that in the first case you use a.myName and in the second b.myName() to get the value of the property.
3) No. If you assign a value to a property of an object, you always have to get that value through the object. In this case either a.myName or a['myName'].

a doesn't make any sense, because you're logging a function reference. B is the way to go, since you're actually invoking the method, using ().

Related

What are the harmful effects of manipulating an object passed in as a parameter? [duplicate]

Eclipse has an option to warn on assignment to a method's parameter (inside the method), as in:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
Normally I try to activate (and heed) almost all available compiler warnings, but in this case I'm not really sure whether it's worth it.
I see legitimate cases for changing a parameter in a method (e.g.: Allowing a parameter to be "unset" (e.g. null) and automatically substituting a default value), but few situations where it would cause problems, except that it might be a bit confusing to reassign a parameter in the middle of the method.
Do you use such warnings? Why / why not?
Note:
Avoiding this warning is of course equivalent to making the method parameter final (only then it's a compiler error :-)). So this question Why should I use the keyword "final" on a method parameter in Java? might be related.
The confusing-part is the reason for the warning. If you reassign a parameter a new value in the method (probably conditional), then it is not clear, what a is. That's why it is seen as good style, to leave method-params unchanged.
For me, as long as you do it early and clearly, it's fine. As you say, doing it buried deep in four conditionals half-way into a 30-line function is less than ideal.
You also obviously have to be careful when doing this with object references, since calling methods on the object you were given may change its state and communicate information back to the caller, but of course if you've subbed in your own placeholder, that information is not communicated.
The flip side is that declaring a new variable and assigning the argument (or a default if argument needs defaulting) to it may well be clearer, and will almost certainly not be less efficient -- any decent compiler (whether the primary compiler or a JIT) will optimize it out when feasible.
Assigning a method parameter is not something most people expect to happen in most methods. Since we read the code with the assumption that parameter values are fixed, an assignment is usually considered poor practice, if only by convention and the principle of least astonishment.
There are always alternatives to assigning method parameters: usually a local temporary copy is just fine. But generally, if you find you need to control the logic of your function through parameter reassignment, it could benefit from refactoring into smaller methods.
Reassigning to the method parameter variable is usually a mistake if the parameter is a reference type.
Consider the following code:
MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);
// what's the value of myObject.Foo here?
public void doFoo(MyObject myFoo){
myFoo = new MyObject("Bar");
}
Many people will expect that at after the call to doFoo, myObject.Foo will equal "Bar". Of course, it won't - because Java is not pass by reference, but pass by reference value - that is to say, a copy of the reference is passed to the method. Reassigning to that copy only has an effect in the local scope, and not at the callsite. This is one of the most commonly misunderstood concepts.
Different compiler warnings can be appropriate for different situations. Sure, some are applicable to most or all situations, but this does not seem to be one of them.
I would think of this particular warning as the compiler giving you the option to be warned about a method parameter being reassigned when you need it, rather than a rule that method parameters should not be reassigned. Your example constitutes a perfectly valid case for it.
I sometimes use it in situations like these:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
to avoid introducing a variable i in the for loop. Typically I only use these kind of 'tricks' in very short functions.
Personally I very much dislike 'correcting' parameters inside a function this way. I prefer to catch these by asserts and make sure that the contract is right.
I usually don't need to assign new values to method parameters.
As to best-practices - the warning also avoids confusion when facing code like:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}
You shoud write code with no side effect : every method shoud be a function that doesn't change . Otherwise it's a command and it can be dangerous.
See definitions for command and function on the DDD website :
Function :
An operation that computes and returns a result without observable side effects.
Command : An operation that effects some change to the system (for
example, setting a variable). An
operation that intentionally creates a
side effect.

With jQuery/JavaScript Is it slower to declare variables that will only be used once?

I just want to make sure I understand this basic idea correctly, and no matter how I phrase it, I'm not coming up with completely relevant search results.
This is faster:
function () {
$('#someID').someMethod( $('#someOtherID').data('some-data') );
}
than this:
function () {
var variableOne = $('#someID'),
variableTwo = $('#someIDsomeOtherID').data('some-data');
variableOne.someMethod( variableTwo );
}
is that correct?
I think the question may be "Is declaring variables slower than not declaring variables?" :facepalm:
The particular case where I questioned this is running a similarly constructed function after an AJAX call where some events must be delegated on to the newly loaded elements.
The answer you will benefit from the most is It does not make a difference.
Declaring variables and storing data in them is something you do so that you do not have to query that data more than once. Besides this obvious point, using variables rather than chaining everything into one big expression improves readability and makes your code more manageable.
When it comes to performance, I can't think of any scenario where you should debate declaring a variable or not. If there's even an absolute difference in speed, it would be so small that you should not see this as a reason to not use that variable and just leaving your code to becoming spaghetti.
If you want to use the element $('#someID') again and again
Then decelaring variable would be useful and caching $('#someId') is recommended.
var x = $('#someId')'

JavaScript optimizations: how to cache local variables' initial values more efficiently?

I'm just curious. Maybe someone knows what JavaScript engines can optimize in 2013 and what they can't? Any assumptions for nearest future? I was looking for some good articles, but still there is no "bible" in the internet.
Ok, let's focus on single quesiton:
Suppose I have a function which is called every 10ms or in a tight loop:
function bottleneck () {
var str = 'Some string',
arr = [1,2,3,4],
job = function () {
// do something;
};
// Do something;
// console.log(Date.getTime());
}
I do not need to calculate the initial values for variables every time, as you see. But, if I move them to upper scope, I will loose on variable lookup. So is there a way to tell Javasript engine to do such an obvious thing - precalculate variables' initial values?
I've careated a jsperf to clear my question. I'm experimenting with different types. I'm especially interested in functions and primitives.
if you need to call a function every 10ms, and it's a bottleneck, the first thought you should have is "I shouldn't call this function every 10ms". Something went wrong in the architecting you did. That said, see 1b in http://jsperf.com/variables-caching/2, which is about four times faster than your "cached" version - the main reason being that for every variable in your code, you're either moving up scope, or redeclaring. In 1b, we go up scope once, to get "initials", then set up local aliasses for its content, from local reference. Much time is saved.
(Concerns V8)
Well the array data itself is not created but an unique array object needs to be created every-time. The backing array for the values 1,2,3,4 is shared by these objects.
The string is interned and it is actually fastest to copy paste same string everywhere as a literal rather than referencing some common variable. But for maintenance you don't really want to do that.
Don't create any new function inside a hot function, if your job function references any variables from the bottleneck function then first of all those variables will become context allocated and slow to access anywhere even in the outer function and it will prevent inlining of the bottleneck function as of now. Inlining is a big deal optimization you don't want to miss when otherwise possible.

What is the cost to convert a javascript variable to jQuery Object?

Sometimes I see in Javascript functions that, if the conversion of a variable to jQuery is used repeatedly, then it can be assigned to a local variable first:
$variable = $(variable);
Is this necessary, and how much is the cost of conversion?
No matter what, storing the object is faster than having to re-instantiate a jQuery object every time you want to use jQuery methods on it...even if it's miniscule for caching $(this) or $(anObject).
A term used to describe this method of "store now, use later" is "caching". The reason it's often called "caching" is because caching refers to storing a reference to something once and using that, without going back out to grab the same thing again, later (very non-technical, non-100% accurate description).
The major point is dealing with selectors. jQuery has to query the DOM every time, which is the expensive part. Generating the object and storing references isn't that expensive compared to DOM manipulation (and jQuery processing your selection in the first place).
If you're simply creating a jQuery object out of an object reference, it's not nearly as devastating, as the processing that takes place is the creation of the jQuery object...so it's really limited to whatever jQuery does for that. It's still good practice and still prevents some unnecessary processing. For example, this:
var element = document.getElementById("div_id");
$(element).someMethod();
// Later:
$(element).someOtherMethod();
is slightly inefficient, since a new jQuery object is created each time. It could easily be condensed to store a reference to a single jQuery object in a variable, and reference that.
The one caveat I can think of is that it isn't a live list of elements (if selecting DOM elements). For example, you may want to cache all elements with the class testing-class, like so:
var myelements = $(".testing-class");
But if another element is added to the DOM with the testing-class class, myelements will not be reflected. It will have the same, previous list. So in that case, the DOM will obviously need to be re-queried and update myelements.
To me, the best practice for caching is within a scope....not the entire page. If you are running a function, and it selects some elements, cache it at the beginning, and use that. But don't cache it globally and use it throughout your page; cache it for an execution cycle.
For example, I would do this:
function someFunc() {
var elements = $(".class-stuff");
// Use `elements` here
// code
// Use `elements` here
someOtherFunc(elements);
}
function someOtherFunc(el) {
// Use `el` here
}
someFunc();
// Some time later:
someFunc();
but I wouldn't do this:
var elements = $(".class-stuff");
function someFunc() {
// Use `elements`
}
function someOtherFunc() {
// Use `elements`
}
someFunc();
someOtherFunc();
// Some time later
someOtherFunc();
It depends on what the variable is. If the original variable is just a single DOM element then it's not particularly expensive - the DOM traversal has already been done so all you're doing is wrapping that element in the jQuery pseudo-array and attaching the prototype.
However if the original variable is a selector, then you absolutely should cache the result to avoid repeated conversions from DOM -> element list.
In any event, it's good practise not to repeat yourself, so caching $(variable) is just good code hygiene.
If the $(variable) is being called anyway this assignment has basically no cost -- this is only storing a reference to the object in memory.
Purists might point out that because the jQuery object is now stored it can't be garbage collected, and this is true. So I guess if you had lots of these it could cause a memory issue, but in itself it has no cost to speak of.
The reason it is done is because there is a cost associated with creating the object, that is the $(variable) part. That if done many times could be expensive. Store a reference to the object means only one needs to be created.
Another important point: The following statement
var $variable = $(variable);
could act different if it is done in a calling context of a closure. That is if there is a function defined in the scope of the var statement that variable will "stick around" for the function to use. This could have the same effects as described above (no gc and pointer memory) with the addition of a longer lifetime. (Because it will stay as long as the function has potential to be called.)

What is the correct way to "serialize" functions in javascript for later use

I have a "library" of objects that I want to load on the fly from a database. Each object comes with its own special functions that are called at specific times depending on the objects type. Ideally I'd like to be able to do this, although its been pointed out that this doesn't work:
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
The string "myObj" is passed around my program quite a bit, but I only have to access certain values of the object at a time, and in some circumstances there's a specific function that needs to be run. The problem is that I'm looking at hundreds, and eventually thousands, of potential objects that could exist with varying functions.
What is the "right" way to store a function to be called like this. I know that calling eval can be very unsafe during execution, enabling xss attacks and whatnot. I really want to avoid a massive switch statement or the bloated loading of additional functions. I'd also like the solution to be as concise as possible.
This can't be the first time this has come up. ;/
Thanks for your help.
Just use eval to recreate the function after loading it as a string. So if you deserialize an object myObj from JSON, and you have a property:
myObj = {
....
function: "function() { ... }"
}
you can very easily turn it to a real function:
eval("myObj.func = " + myObj.func);
http://jsfiddle.net/kceTr/
Oh - I am not sure if that was an edit or I missed it before - but re: eval.
Eval is a tool. You want to store a function in a database. It really doesn't make much difference if you have to "eval" to turn it into code, or there was some other magic way to do it: if someone can change the data in your DB, then they can change a function.
If you need to store a function, then eval is your tool. It's not "bad" by nature, it's bad because it's easy to misuse. Whether you use it well or not is up to you.
Remember anything running on the client is still just running on the client. There's nothing a malicious person could do with eval, that they couldn't do with the Chrome debugger a lot more easily. Anyone can always run any code they want on the client, it's up to your server to decide how to handle what it receives. There's nothing safe on the client in the first place...
Changing the prototype of the object is a half thought I have.
You've got your library like
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
You've got an object (let's call it theObj) that you know is a myObj (due to a string maybe? property?)
theObj.__proto__ = library["myObj"];
That way you can execute
theObj.function(...);
jsfiddle example (it's rough!). Also, be careful with proto, it's deprecated (1) (2)
As to serializing the functions, can you get them in using a script tag that points to something serverside that slurps them from the db and returns the js? Just include them inline as you render the page (in a script block)? Or, if all else fails, eval should work, as long as you know that the functions you've got stored in the database are clean and safe.
There is no right way to do this, because its not generally a good idea.
HOWEVER, if you want to do it anyways you can simply extend the prototype of Function with a .toJSON method.
Function.prototype.toJSON = function(){ return this.toString(); }
Then you can simply use JSON.stringify and functions will be serialized as strings.
Its generally a not good idea in most cases. There are very few circumstances where you want to do this and even then, there is probably a better way.
A better approach might be to serialize the object's properties when you "sleep" it, and "waking" the object by reattaching its properties to a new instance of the object with the appropriate methods defined.
what you are doing with it is just fine. However, if i were you, for readability and tidyness, i would rather have the function created outside and simply have it assigned to your object key.
You don't need eval here. Instead do it this way whenever you want access to the stored function -
library.myObj.function()
You do your best in parameterising your functions, so that you end up
with as little typologies as possible.
Store them on the server in individual JS files, then load the needed file dynamically, by name.
In the JSON, only store the name of the file that contains the function that you need. And, of course, you will be caching already loaded files, to go easy on the server.
Just my two cents.
You can only really serialise a whole file with require calls in it. If you do that, you can create a module, exports and module.exports, eval the file with a function surrounding it and snag the module.exports out of it.
It's not exactly secure, but for that you need to use something like VM2 and value-censorship (which I've been working on) to avoid them calling eval() and owning your machine or the entire network.

Categories

Resources