Javascript global namespace and dynamic property question - javascript

Say I want to have a global object which can be visible and accessible across pages(??)
// core.js
var MyLib = {}; // global Object cointainer
MyLib.value = 1;
If I define this way, then I can have access to MyLib.value in other places as long as I load the core.js.
However, if I want to add new property to object MyLib in somewhere else, say:
//extra.js
MyLib.otherVal = 2;
Then I try to access MyLib.otherVal from a different place, it is not available. I probably have some fundamental misunderstanding on how this suppose to work. I hope someone can enlighten me.
After reading the comments, I realized the scope I want is indeed across pages. Is that even possible?
thanks
Oliver

If you want to carry data across pages, there are really three major methods:
LocalStorage. See this page for a fairly thorough explanation of the concept, how to use it, and so forth. Here is a library dealing with JavaScript storage.
Cookies. Cookies can store 4KiB of data, but some users disable them.
window.name. You can store up to 2MiB of data in window.name. Here is a library that focuses on storing data in window.name; it seems fairly well-written.
You could potentially write an app to take advantage of all three of these techniques, starting with LocalStorage and falling back to window.name if all else fails.

Related

What scenario would i use a proxy? Javascript [duplicate]

I recently got to know about ES6 proxies but I don't see a good reason to use it. I mean, everything that one could do with Proxy can be done without it, except if I'm missing something.
For example, most folks talk about validation when it comes to proxy but one could apply some JS goodness to validate and everyone is fine. I would appreciate if someone could open my eyes to some major use cases of Proxies. Thanks!
I mean, every thing that one could do with Proxy can be done without it...
That isn't remotely true.
Consider the common need to catch access to properties that don't exist:
const o = {foo: "bar"};
console.log(o.blarg);
It's common to want to handle that in a way other than the default, which is to log undefined. Proxy lets us do that, via the get trap. Example:
const o = {foo: "bar"};
const p = new Proxy(o, {
get(target, prop, receiver) {
return prop in target ? target[prop] : "nifty!";
}
});
console.log(p.foo);
console.log(p.blarg);
Another example is the ability to hook into the various operations that get the list of properties on an object. There is no way to hook into that without Proxy. With Proxy, it's easy: You use the has trap or the ownKeys trap depending on what you want to hook into.
In terms of other use cases: Proxy is the ultimate tool for implementing the Facade pattern. Look for the use cases of Facade, and you'll find use cases for Proxy.
There is actually lots you can do with it. Theres an awesome github repo where this guy put together a bunch of proxy resources which you can check out.
https://github.com/mikaelbr/proxy-fun
Also, check out my gists, I recently started playing around with proxies, and I have a couple examples that are pretty unique. You can essentially build your own DSL using proxy and program in a closer fashion to the way you think.
https://gist.github.com/jasuperior
Proxies represent a class of dynamic programming (as in dynamic languages, not the method of problem solving) called metaprogramming, and it is absolutely not the case that anything that can be done with proxies can be done without them. In fact that's really the reason proxies exist: to enable entirely new capabilities that weren't possible before.
Proxies enable you to intercept operations on your objects that would have otherwise been purely the responsibility of the JavaScript engine; property accessing and mutating being the two obvious examples.
T.J.'s answer is a good example of something you can't do without proxies. To give you another, I am using proxies to enable singleton instances of objective entities to allow their backing data stores to be swapped-out and replaced with entirely new objects, without affecting the references that are pointing to those objects.
To do this without proxies, we would have to iterate over each field of the object and swap them out for the new fields in the new object. While it's true JavaScript is dynamic enough to allow that to be possible, Proxies allow it to be solved in a much more elegant way: the hidden backing store of the proxy is simply replaced with the new object and all future property accesses are simply directed to the new backing store rather than the old one, while external references to the object (which is actually the proxy) need be none the wiser. To them, it appears as though it is the same object (because it is), but now it happens to have completely different data behind it.
This is only one example of what you can use Proxies for. They are really quite powerful because of how dynamic they are. I'm just getting to know them, but already I can say I'm quite in love. :)
In ES6 Proxy offers the flexibility of eating your cake and having it back. You do not need to know beforehand the properties going to be get/set like in ES5.
Now with ES6 Proxy you can add new property to an object like so: proxyObj.newProp = 9, Proxy will smile and set the new property without prejudice.

Major use cases for ES6 proxies

I recently got to know about ES6 proxies but I don't see a good reason to use it. I mean, everything that one could do with Proxy can be done without it, except if I'm missing something.
For example, most folks talk about validation when it comes to proxy but one could apply some JS goodness to validate and everyone is fine. I would appreciate if someone could open my eyes to some major use cases of Proxies. Thanks!
I mean, every thing that one could do with Proxy can be done without it...
That isn't remotely true.
Consider the common need to catch access to properties that don't exist:
const o = {foo: "bar"};
console.log(o.blarg);
It's common to want to handle that in a way other than the default, which is to log undefined. Proxy lets us do that, via the get trap. Example:
const o = {foo: "bar"};
const p = new Proxy(o, {
get(target, prop, receiver) {
return prop in target ? target[prop] : "nifty!";
}
});
console.log(p.foo);
console.log(p.blarg);
Another example is the ability to hook into the various operations that get the list of properties on an object. There is no way to hook into that without Proxy. With Proxy, it's easy: You use the has trap or the ownKeys trap depending on what you want to hook into.
In terms of other use cases: Proxy is the ultimate tool for implementing the Facade pattern. Look for the use cases of Facade, and you'll find use cases for Proxy.
There is actually lots you can do with it. Theres an awesome github repo where this guy put together a bunch of proxy resources which you can check out.
https://github.com/mikaelbr/proxy-fun
Also, check out my gists, I recently started playing around with proxies, and I have a couple examples that are pretty unique. You can essentially build your own DSL using proxy and program in a closer fashion to the way you think.
https://gist.github.com/jasuperior
Proxies represent a class of dynamic programming (as in dynamic languages, not the method of problem solving) called metaprogramming, and it is absolutely not the case that anything that can be done with proxies can be done without them. In fact that's really the reason proxies exist: to enable entirely new capabilities that weren't possible before.
Proxies enable you to intercept operations on your objects that would have otherwise been purely the responsibility of the JavaScript engine; property accessing and mutating being the two obvious examples.
T.J.'s answer is a good example of something you can't do without proxies. To give you another, I am using proxies to enable singleton instances of objective entities to allow their backing data stores to be swapped-out and replaced with entirely new objects, without affecting the references that are pointing to those objects.
To do this without proxies, we would have to iterate over each field of the object and swap them out for the new fields in the new object. While it's true JavaScript is dynamic enough to allow that to be possible, Proxies allow it to be solved in a much more elegant way: the hidden backing store of the proxy is simply replaced with the new object and all future property accesses are simply directed to the new backing store rather than the old one, while external references to the object (which is actually the proxy) need be none the wiser. To them, it appears as though it is the same object (because it is), but now it happens to have completely different data behind it.
This is only one example of what you can use Proxies for. They are really quite powerful because of how dynamic they are. I'm just getting to know them, but already I can say I'm quite in love. :)
In ES6 Proxy offers the flexibility of eating your cake and having it back. You do not need to know beforehand the properties going to be get/set like in ES5.
Now with ES6 Proxy you can add new property to an object like so: proxyObj.newProp = 9, Proxy will smile and set the new property without prejudice.

localStorage - use getItem/setItem functions or access object directly?

Are there some benefits of using the methods defined on the localStorage object versus accessing the object properties directly? For example, instead of:
var x = localStorage.getItem(key);
localStorage.setItem(key, data);
I have been doing this:
var x = localStorage[key];
localStorage[key] = data;
Is there anything wrong with this?
Not really, they are, basically, exactly the same. One uses encapsulation (getter/setter) to better protect the data and for simple usage. You're supposed to use this style (for security).
The other allows for better usage when names(keys) are unknown and for arrays and loops. Use .key() and .length to iterate through your storage items without knowing their actual key names.
I found this to be a great resource : http://diveintohtml5.info/storage.html
This question might provide more insight as well to some: HTML5 localStorage key order
Addendum:
Clearly there has been some confusion about encapsulation. Check out this quick Wikipedia. But seriously, I would hope users of this site know how to google.
Moving on, encapsulation is the idea that you are making little in and out portals for communication with another system. Say you are making an API package for others to use. Say you have an array of information in that API system that gets updated by user input. You could make users of your API directly put that information in the array... using the array[key] method. OR you could use encapsulation. Take the code that adds it to the array and wrap it in a function (say, a setArray() or setWhateverMakesSense() function) that the user of your API calls to add this type of information. Then, in this set function you can check the data for issues, you can add it to the array in the correct way, in case you need it pushed or shifted onto the array in a certain way...etc. you control how the input from the user gets into the actual program. So, by itself it does not add security, but allows for security to be written by you, the author of the API. This also allows for better versioning/updating as users of your API will not have to rewrite code if you decide to make internal changes. But this is inherent to good OOP anyhow. Basically, in Javascript, any function you write is a part of your API. People are often the author of an API and it's sole user. In this case, the question of whether or not to use the encapsulation functions is moot. Just do what you like best. Because only you will be using it.
(Therefore, in response to Natix's comment below...)
In the case here of JavaScript and the localStorage object, they have already written this API, they are the author, and we are its users. If the JavaScript authors decide to change how localStorage works, then it will be much less likely for you to have to rewrite your code if you used the encapsulation methods. But we all know its highly unlikely that this level of change will ever happen, at least not any time soon. And since the authors didn't have any inherent different safety checks to make here, then, currently, both these ways of using localStorage are essentially the same. Except when you try to get data that doesn't exist. The encapsulated getItem function will return null (instead of undefined). That is one reason that encapsulation is suggested to be used; for more predictable/uniform/safer/easier code. And using null also matches other languages. They don't like us using undefined, in general. Not that it actually matters anyhow, assuming your code is good it's all essentially the same. People tend to ignore many of the "suggestions" in JavaScript, lol! Anyhow, encapsulation (in JavaScript) is basically just a shim. However, if we want to do our own custom security/safety checks then we can easily either: write a second encapsulation around the localStorage encapsulate, or just overwrite/replace the existing encapsulation (shim) itself around localStorage. Because JavaScript is just that awesome.
PT
I think they are exactly the same, the only thing the documenation states is:
Note: Although the values can be set and read using the standard
JavaScript property access method, using the getItem and setItem
methods is recommended.
If using the full shim, however, it states that:
The use of methods localStorage.yourKey = yourValue; and delete
localStorage.yourKey; to set or delete a key is not a secure way with
this code.
and the limited shim:
The use of method localStorage.yourKey in order to get, set or delete
a key is not permitted with this code.
One of the biggest benefits I see is that I don't have to check if a value is undefined or not before I JSON.parse() it, since getItem() returns NULL as opposed to undefined.
As long as you don't use the "dot notation" like window.localStorage.key you are probably OK, as it is not available in Windows Phone 7. I haven't tested with brackets (your second example). Personally I always use the set and get functions (your first example).
Well, there is actually a difference, when there is no local storage available for an item:
localStorage.item returns undefined
localStorage.getItem('item') returns null
One popular use case may be when using JSON.parse() of the return value: the parsing fails for undefined, while it works for null

How to destroy a JavaScript object?

Recently, I came across one of my application which consumes too much memory and increasing by 10 MB/sec.
So, I like to know how to destroy JavaScript object and variables so memory consumption stays down and my FF can't get destroyed.
I am calling two of my scripts every 8 seconds without reloading the page.
function refresh() {
$('#table_info').remove();
$('#table').hide();
if (refreshTimer) {
clearTimeout(refreshTimer);
refreshTimer = null ;
}
document.getElementById('refresh_topology').disabled=true;
$('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
$("#topo").hide();
$('#root').remove();
show_topology();
}
How can I see which variable cause Memory overhead, what's the method to stop the execution of that process?
You could put all of your code under one namespace like this:
var namespace = {};
namespace.someClassObj = {};
delete namespace.someClassObj;
Using the delete keyword will delete the reference to the property, but on the low level the JavaScript garbage collector (GC) will get more information about which objects to be reclaimed.
You could also use Chrome Developer Tools to get a memory profile of your app, and which objects in your app are needing to be scaled down.
You can't delete objects, they are removed when there are no more references to them. You can delete references with delete.
However, if you have created circular references in your objects you may have to de-couple some things.
While the existing answers have given solutions to solve the issue and the second half of the question, they do not provide an answer to the self discovery aspect of the first half of the question that is in bold:
"How can I see which variable causes memory overhead...?"
It may not have been as robust 3 years ago, but the Chrome Developer Tools "Profiles" section is now quite powerful and feature rich. The Chrome team has an insightful article on using it and thus also how garbage collection (GC) works in javascript, which is at the core of this question.
Since delete is basically the root of the currently accepted answer by Yochai Akoka, it's important to remember what delete does. It's irrelevant if not combined with the concepts of how GC works in the next two answers: if there's an existing reference to an object it's not cleaned up. The answers are more correct, but probably not as appreciated because they require more thought than just writing 'delete'. Yes, one possible solution may be to use delete, but it won't matter if there's another reference to the memory leak.
Another answer appropriately mentions circular references and the Chrome team documentation can provide much more clarity as well as the tools to verify the cause.
Since delete was mentioned here, it also may be useful to provide the resource Understanding Delete. Although it does not get into any of the actual solution which is really related to javascript's garbage collector.
Structure your code so that all your temporary objects are located inside closures instead of global namespace / global object properties and go out of scope when you've done with them. GC will take care of the rest.
I was facing a problem like this, and had the idea of simply changing the innerHTML of the problematic object's children.
adiv.innerHTML = "<div...> the original html that js uses </div>";
Seems dirty, but it saved my life, as it works!

Javascript optimization...global variables

I am making a webapp. I have a fairly basic question about javascript performance. Sometimes I need a global variable to store information that is used the entire time the website is open.
An example is a variable called needs_saved. It is true or false to say whether the page needs saved. I might have another variable called is_ie, ie_version, or space_remaining.
These are all variable that I need in various functions throughout the app.
Now, I know global variables are bad because they require the browser to search each level of function scope. But, I don't know if there is any better way to store values that are needed throughout the program.
I know I could create a global object called 'program_status' and give it the properties is_ie, ie_version, etc... But is this any better since it would first have to find my program_status object (stored as a global variable), and then the internal property?
Maybe I'm overthinking this.
Thanks
You have nothing to worry about.
The performance impact of a global variable is minute.
Global variables are discouraged because they can make code harder to maintain.
In your case, they won't.
The reason global variable use should be kept to a minimum is because the global namespace gets polluted when there's a lot of them, and there's a good chance of a clash if your program needs to use some 3rd party libraries which also create their own globals.
Creating a single object to hold all of your global state is a good idea since it limits the number of identifiers you need to reserve at the global level.
To solve performance problems, you can then create a local reference to that object in any scope where you need to access it multiple times:
So instead of
if (globalState.isIe) { alert(globalState.ieMessage); }
you can do
var state = globalState;
if (state.isIe) { alert(state.ieMessage); }
You don't need to do this if you only access the state object once. In any case, even if you never do this, the performance penalties will be negligible.
If you're worried about performance, code something clean then run a profiler on it to optimize. I know both Safari and Google Chrome have one, and it's pretty sure Firebugs includes one for Firefox too. Heck, even Internet Explorer 8 has one.

Categories

Resources