I can understand the purpose of clone() method when appending a copy element like this:
$aObject = $('.className').clone();
$aObject.removeAttr('id');
$('#add-line').click(function() {
$('#container').append( $aObject.clone());
});
But what I don't understand is, if I get rid of the clone method, just using
$('#container').append( $aObject);
I should still be able to add multiple same object to the container, but it seems like I can only add the aObject once? can't we add same object many times on purpose just like an array of same objects?
When you assign an object to a variable in JavaScript, you aren’t actually assigning the object value stored in memory – rather a reference that points to the object’s location in memory.
So, when you declare $aObject, you have now stored a reference to a particular object. When you append it, it behaves as you would expect, appending the object that you are referencing. When you try to do the same thing again, it is referring to the same object that now already exists in the DOM and simply takes that object and re-appends it (what Scott Marcus meant when he said it acts as move).
If you clone it first, then you are referencing an entirely different object, which can be appended in addition to any objects you've already appended.
Related
I have some global vars, which I know, bad code and all.
One of these vars: MyApp.player.pet, is an object of type pet, attached to the player object. It has some properties like "xp" which is just a number.
I am passing this object to a dynamic UI class that displays information about all kinds of objects, which is why I can't use the reference to the global var inside the object. Here is how I pass it:
var listOfProperties =
[MyApp.player.pet.name,
{"xp: ": MyApp.player.pet.xp},
{"xpToNextLevel: " : MyApp.player.pet.xpToNextLevel}];
then I transfer this list of properties to a new UI object as such:
new tooltipText(listOfProperties, ..., ...)
However, when the value gets updated inside MyApp.player.pet.xp the value inside the object tooltipText doesn't change. Somehow it's passing a copy, but I want to pass a reference if those are correct terms.
I've tried searching for this but all I can find are people asking how to make copies of objects, which seems to be what I've done unintentionally but not what I want.
How can I make sure that when MyApp.player.pet.xp changes, the value inside the tooltiptext also changes?
There is some misconception in your question:
You did not create copies of your original objects.
You merely copied some of their property values, by putting them into new objects (e.g. {"xp: ": MyApp.player.pet.xp}).
If you want to change the properties of your original objects, you need to change them there, not in your newly created small objects.
So if you want a generic list of properties, you need to keep a reference to your original object (MyApp.player.pet) as well. Example:
var listOfProperties = {
obj: MyApp.player.pet,
propertyNames: ['xp', 'xpToNextLevel']
}
You can then use the property names to generically set the properties of your original object:
var propertyName = listOfProperties.propertyNames[0];
listOfProperties.obj[propertyName] = newValue;
I'm currently in the learning process of JavaScript and really get confused about immutable values. What I understand is, when a value is created (stings/numbers/booleans), it can never be changed.
Now my question is, the variable that I assign values, the value of that variable is changeable. I can assign new values to that variable. So why immutability is important?
Also, when I assign a new value to a variable, what happen to the previous value? Does it stay in memory and block some spaces? Does it lost its pointer from that variable? Actually what happen?
Please help me to understand what is the actual use of the concepts "Mutable" and "Immutable" in JavaScript. Thanks in advance.
What You Seem Confused About
Assignment of a variable has nothing to do with immutable or mutable objects. A variable is simply an alias: it refers to an object in memory. When you change a variable's value, all you've done is tell the compiler to stop associating that object with this variable and associate it with another object instead. Assignment does not affect the underlying object - the object never changes, you just no longer have a way to access it anymore.
Usually, when all references to an object are lost, they are garbage collected i.e. the memory allocated for the object is released and the object is lost forever. However, this also has nothing to do with the difference between immutable and mutable objects.
The Real Difference Between Immutable and Mutable Objects
Immutable objects do not modify the object in place (i.e change what it looks like) - they return a new copy of the data with the variables changed.
Mutable objects in Javascript do not return a copy, but let you change the object itself.
I liken it to the difference between array.splice() and array.slice(). splice() will change the original array by removing/inserting elements where needed - slice() will create a new array with just the elements you want. They can be made to do the same things - but one mutates the array in place, the other one creates a copy.
An immutable object is forced to always return a new copy when changed - it will not by itself be changed. A mutable object can - but does not have to - be mutated in place. Primitive types in Javascript are mostly immutable - you cannot change the form of a string once created (if you call replace on the JS string, you will receive a new string with the values you asked for replaced, not the same string with the value changed). Objects are mostly mutable: for instance you can do object[key] = value and change the object everywhere it is referenced.
tl;dr
When you change a mutable object, it is changed everywhere it is referenced. When you change an immutable object, it isn't changed at all - a new object is created, and all the old references to the object will give you the original object with nothing different about it.
All:
I am new to DOM, I got one question about DOM reference, for example(suppose I use D3.js or jQuery):
var domelement = d3.select("div#chart");
d3.select("div#chart").remove();
console.log(domelement);
When I print domelement, it still show an Object in the console even though it has been deleted from the DOM structure.
So I am wondering, why this variable still has access to the DOM object?
How can I decide if a reference is invalid?
Thanks
So I am wondering, why this variable still has access to the DOM object?
You retrieved a reference to an object in memory and your variable will retain it for as long as you have it in scope.
You can mutate an object having a reference to it but you cannot destruct it (not in JS).
How can I decide if a reference is invalid?
There is no such a thing as "invalid" reference. If you want to check if the element is still mounted in the DOM - you can just try to search for it. If it's there - you'll find it, and you will not otherwise.
.remove() returns the value (like a return function in javascript). When you use console.log this value is printed but it no longer exists in the DOM. HTML elements can exist as data nodes in javascript (document.createElement).
In this state, they exists as data, but haven't been added anywhere where they'd be visible. .remove() cuts the element out of the body and returns it in its data form, then console.log prints it.
Consider this setup:
function makeObj(a){
this.foo = 'bar';
this.prototype = a;
}
b = makeObj(document.getElementById('foo'));
document.getElementById('bar').appendChild(b);
this gives an error:
Node cannot be inserted at the specified point in the hierarchy" code: "3
Why so? Object b has a valid element as its prototype. Shouldn't it have worked?
There are several issues here.
First makeObj() isn't making a new object at all. It's just a function call and this in that function call is likely referring to the window object. You would have to use makeObj() with the new operator to actually create a new javascript object.
Secondly, you can only append DOM objects to the DOM, not regular javascript objects.
Thirdly, just assigning a DOM object to another object's prototype does not make that other object suddenly become a DOM object. If you want a DOM object, you need to create a DOM object using something like createElement() or one of the other documented ways of creating DOM objects.
If you can describe more about what you're really trying to accomplish, we could advise further.
As many of you are aware, the javascript delete keyword is a little tricky to use (see here). Is it possible to re-implement, or modify it? I have an object referenced multiple times and I want delete to remove all the references first. Like so:
var oj = new OrangeJuice();
var juice = oj;
var beverage = oj;
var allRightSunnyD = oj;
delete oj; //I want this to delete the actual object
I do not expect the garbage collector to find all of the references, lets say I know where the references are, i just want to re-implement delete to also get rid of juice, beverage and allRightSunnyD. I realize I could just implement a OrangeJuice.delete() function, but I wanted to know if there was a way to do it right. Like if javascript would call an onDelete() callback function prior to deleting objects.
delete is a keyword, so it should not be altered even if you can
delete is for deleting properties of objects, so you can not delete objects contained in single variables
look here how garbage collection in Javascript is explained: How does garbage collection work in JavaScript?