How to correctly dereference then delete a JavaScript Object? - javascript

I would like to know the correct way to completely dereference a JavaScript Object from memory. To ensure it's deletion without it dangling in memory, and that the garbage collector removes the object.
When I looked and this question Deleting Objects in JavaScript. It was explained that if you delete all the references of object, the GC will remove it from memory. I want to know how do I go about removing references from an object that has both methods and properties.
Suppose you have and object that was created by using function, and the object has both methods and properties. Say it looks something like this:
function myObject(x, y) {
this.x = x;
this.y = y;
this.myMethod = function() {
// method code
}
}
var myInstance = new myObject(24, 42) // How to remove this completely?
Note: This is an example, I understand you can use prototype for methods.
I know I can't just say delete myInstance. So in this case to completely delete the object will I need to call delete on all it's properties, and then call delete on the instance, like so?
delete myInstance.x;
delete myInstance.y;
delete myInstance; // I'm not sure if this is necessary.
Would this work? Or do I need to also delete it's methods (and if so how)?
Or perhaps there is a better and simpler way to do this?

Javascript is a garbage collected language. It will clean up an object ONLY when there is no other code that has a reference to it. Those other references need to either go out of scope (and not be held by a closure) or you can set those other variables to something else so they don't point at your object. When there are no other variables with a reference to your object, it will be automatically taken care of by the garbage collector, including any properties it has (assuming none of those properties are themselves objects that something has a reference to - but even then the host object would be cleaned up and only the object in the property would continue to live on).
You cannot delete an object any other way in Javascript.
So, to remove the object created by this:
var myInstance = new myObject(24, 42) // How to remove this completely?
Just clear myInstance like this:
myInstance = null;
You don't need to manually delete the properties from myInstance at all. If nobody has a reference to the mother object and none of the properties are objects that someone has a reference to, then the garbage collector will just clean everything up for you.
The delete operator is primarily for removing properties from an object when you want the mother object to remain (e.g. when you just want to remove a property).

Related

What is _proto_ and why is it always present faded away in any JS Object?

Whenever I open an object details in console.log, after the attached properties or functions I always see "_ proto _". What is this and why is it always present even though I never declared anything like this in my object? I know it is related to some prototype feature but not exactly sure. Also, whereever it exists, whether plain js, jquery, or Angular.js it has the exact same 13 functions below it, viz. defineGetter, defineSetter, ...., set_proto.
Can someone explain it?
So whenever you make any object in JavaScript it inherited from Object. so a object in java script have this structure
private members
proto-Reference of the prototype of current object parent.
prototype- Reference of the current objects prototype
So if you make any object let say named as object1
var object1=new Object();
it will be inherited from Object. and have proto set to Object(you can think Object as root class).

Use cases of Object.create(null)?

If you create a regular javascript object using say var obj = {}; it will have the object prototype. Same goes for objects created using var obj = new MyClass(); Before Object.create was introduced there was no way around this. However nowadays it's possible to create an object with no prototype (respectively null as its prototype) using var obj = Object.create(null);.
Why is this important? What advantages does it bring? Are there any real world use cases?
It's a completely empty object (nothing inherited from any .prototype including Object.prototype), so you can be guaranteed that any property lookup will only succeed if the property was explicitly added to the object.
For example, if you want to store some data where you won't know the keys in advance, there's a possibility that a provided key will have the same name as a member of Object.prototype, and cause a bug.
In those cases, you need to do an explicit .hasOwnProperty() check to rule out unexpected inherited values. But if there's nothing inherited, your testing can be simplified to a if (key in my_object) { test, or perhaps a simple truthy test if (my_object[key]) { if appropriate.
Also, with no prototype chain, I would imagine that lookups of properties that turn out to not exist would be faster, since only the immediate object would need to be checked. Whether or not this pans out in reality (due to optimizations) would be determined with performance testing.
The only difference here between creating an object with {} and Object.create(null) is that the Object prototype will not be inherited from.
This means that any of the methods we typically assume we can call on any object will not exist, such as toString and valueOf. A list of these can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
From a performance perspective, creating an object simply by {} is actually much faster, so unless you specifically cannot have the functions under the Object prototype you should not create objects in that manner.
http://jsperf.com/null-vs-empty-object-performance

How to obtain true de-referenced object instances in javascript

I'm trying to get a better understanding of object oriented patterns in JavaScript. I particulary like the way EmberJS implements their classes with .extend and .create from Parent class Objects.
I've tried to implement a basic version of this on my own, but to no success, my newly instantiated Objects reference the same Object. I.e If I increment a private counter var in instance a via a public method, then separately do the same to instance b, b will reflect both increments.
I was able to achieve a de-referenced object via Object.create(myClass), however this is undesirable as I'd like to achieve this internally and also not rely on client support for that native method.
Here's a jsbin of what I've got: http://jsbin.com/zepaju/6/edit?js,console
Thanks for any help!
This is a pretty big subject, because there isn't a perfect way to make JavaScript work like Java-- you'll always have to invent some new coding idiom, and different people have different preferences.
Looking at your linked code, it's hard to be sure what you're gunning for but it looks like the problem is that you're thinking of an object's prototype as a "class", which is copied into each "instance" (like in Java)-- this isn't the case.
Your create() function is creating each "instance" by doing Object.create(Poll), which makes a new object with the Poll object as its prototype. When you refer to properties of the resulting objects, and those properties are not directly defined on the object, what you get is a reference to a property of the single Poll object.
The fact that you've sealed the Poll object's internal variables within a closure doesn't make any difference to this; the closure variables are hidden from the outside world, but they are accessible to the methods of the Poll object, and those methods are shared between all "instances".
If you want a function that spits out objects with a particular set of methods, and which hide their internal data in a closure, that might look like:
function Poll(challenger,incumbent) {
var challengerVotes=0;
var incumbentVotes=0;
return {
voteForChallenger: function() {challengerVotes++},
voteForIncumbent: function() {incumbentVotes++},
winner: function() {return challengerVotes>incumbentVotes ? challenger : incumbent}
}
}
var poll1 = Poll("Edward","Jacob");
var poll2 = Poll("Vanilla","Stilton");
poll1 and poll2 would not affect one another, and there would be no way to access the vote counts of either except through the supplied methods. I appreciate you're looking for a more generic approach but this is an example of how you might start.

What is the use of creating a class in javascript, if I can insert any attritube to an object any time

Consider the below code.
I created an empty object. And am adding var1,var2,var3 without declaring them.
var har = new Object();
har.var1 = "Var1";
har.var2 = "Var1";
har.var3 = "Var1";
alert( har.var1 );
If I can do this, then why do I need to create a Class and fix the attributes when I can introduce new attributes anytime?
Why would you even need to use objects in the first place? Non-object-oriented languages are already Turing-complete, so everything you can accomplish with objects you can also do without them.
What you're showing in your example is not really an object, but just a dictionary. In cases like this, where you only need to keep several related properties together, anonymous unprototyped objects like the one you're using are the de-facto standard approach (though it is customary to initialize them with the shorthand syntax, e.g. var har = {}). It is an object, since it uses the object data structure, but it is not object-oriented.
Actual objects, in contrast, not only define data, but also the operations that you can perform on that data. Objects have not only properties, but also methods which work on these properties. These properties are usually defined in the object prototype (which you're calling "class", but Javascript is not a class-based language, but a prototype-based one). All methods defined in the prototype are shared between all instances of that prototype.
function Counter() {
this.counter = 0;
}
Counter.prototype.increment = function() {
this.counter++;
alert(this.counter);
}
var c1 = new Counter();
var c2 = new Counter();
c1.increment(); // alerts 1
c1.increment(); // alerts 2
c2.increment(); // independent from c1: alerts 1 again
Each instance is still a dictionary, as in your example (and you can even still add more properties to them, they are not "fixed" by having a constructor and prototype), but now it can also perform tasks on its properties. This can be done your way as well:
c1 = {
counter: 0,
increment: function() {
this.counter++;
alert(this.counter);
}
}
c2 = {
counter: 0,
increment: function() {
this.counter++;
alert(this.counter);
}
}
You can see, however, that if you need two counters, without using prototypes you will need to duplicate your entire object definition. This will be cumbersome to write and maintain, and each increment function will be defined separately, thus it will also waste memory.
That said, in cases where you need an object that you know you'll only ever need one instance of, it makes no sense to define a constructor and a prototype for it. Such objects are usually regarded as namespaces instead of actual objects.
Appendix: Dictionaries vs Objects
A dictionary is a data structure which holds named elements. Besides "dictionary", they are also called associative arrays or hashmaps. Objects in Javascript are implemented as dictionaries — each property is a named element in the dictionary. In addition to a plain dictionary, objects also have a prototype, which is kind-of like a parent object — when you look up a named element in the dictionary and it is not there, it is automatically searched for in the prototype as well. This way, default properties and methods are defined only once in the prototype, and do not need to be copied into each instance. (The prototype of an object is often visible as the instance.__proto__ property, though this is non-standard and deprecated even in browsers that support it; the actual prototype is defined as an internal, non-accessible property by the standard)
So, Javascript objects are actually dictionaries. When you want to use a plain dictionary to store some related properties together, there is no separate syntax in Javascript to create a dictionary that is not an object, so you create an instance of the base Object type to hold your dictionary (it does not matter if you do var dict = new Object or var dict = {}, the result is the same); thus, dictionaries that you use in your code are also objects.

How does the browser's javascript garbage collection work?

Do I have to destroy instances myself? ...if I don't assign them a variable...will they automatically go away?
new ImageUploadView();
vs
var Iu = ImageUploadView();
If there is no reference to an object in javascript, the garbage collector will clean it up.
The way the garbage collector works is it looks for javascript objects for which nobody has a reference to. If nobody has a reference to it, then it can't be used again, so it can be deleted and the memory it occupied reclaimed. On the other hand, if any javascript entity still has a reference to the object, then it is still "in use" and cannot be deleted.
In your first code example:
new ImageUploadView();
unless the constructor of the object stores away the this pointer into some other variable or object or creates some closure that causes references to the object to be held, then there will be no reference to this new object and it will be cleaned up by the garbage collector.
If you second code example:
var Iu = ImageUploadView();
as long as the Iu variable exists and stays in scope it will contain whatever the ImageUploadView() function returns. Note, the second example, is just executing a function and storing it's value. It is not necessarily creating anything. If ImageUploadView() just returns true, then that's all the Iu variable will contain.
The first method is fine. Assuming that the instance of ImageUploadView is appropriately cleaning up after itself, it will be collected by the garbage collector.
With large objects, it's not necessarily a good practice to assume that the browsers built in garbage collector will clean up once it's out of scope. You're better off to clear it ourself using "delete". For example:
delete MyImageUploadView;
Edit: it may be preferable to set the object to null if it isnt being referenced as a property.

Categories

Resources