From what I know, javascript, that is also based on ECMAscript the same as actionscript, does not really pass objects by reference. At least that's what I've read lately. For instance:
function doStuff(myObj){
myObj.name = 'groovy chicken';
myObj = null;
}
var newObj = new Object();
doStuff(newObj);
This is an example I found in a book 'Professional Javascript for web developers'. Although you are passing an object to the function, and adding the name property actually adds the property to your initial object, when you set to null, the object is destroyed in the local scope not in the global scope.
To me, this is still a bit confusing, since the myObj you have, is still pointing the same place as newObj and you can actully add or alter properties. The only difference is that you can not destroy it from the global scope.
So I'm wondering if the same also applies to actionscript, since from what I've read, actionscript 3 does actually pass objects by reference and I've not read anything stating the opposite.
Very few modern programming languages pass by reference (at least by default). In the twisted terminology of "pass by..", you're passing a reference by value. Here's how to think about it:
myObj and newObj are just variables, names for things.
The value of those variables are references to the object
When you call doStuff(), you're binding the name myObj to a new reference to your object (i.e. the reference itself was passed by value)
The reference points to a chunk of memory with some stuff in it, which is what lets you change the name inside of doStuff()
You can see that change by inspecting either variable because both variables contain references to the same object
myObj = null reassigns the variable to nothing, and in the process, it "destroys" the reference, but it doesn't destroy the object.
When the garbage collector notices there are no more references to an object, it will destroy that object
I'll try to help you understand the working of JavaScript's object:
when you say,
var newobj = new Object();
Here, newobj is only a name to the memory location allocated when you created an instance of Object.
When you pass newobj, it takes along the reference to the memory location. Now, myObj in the function is another name to the same memory location.
Adding a method 'name' adds it to the memory location and hence is available to both newobj and myobj.
when you set myobj to null, it removes that named reference and newobj still remains alive with the name property set.
But, I dont have an idea on how this works in actionscript.
Related
I am trying to understand prototypes and dealing with some interference from my understanding of various other constructs.
Can someone explain to me what Object is in Javascript? To clarify, I know what an object(with a lower-case 'o') is, but not what Object (with a capital 'O') is. I understand that any object that is created in JS has a hidden prototype object attached to it. The prototype object is both a property of the parent object, and an object itself, with its own properties that can be accessed using the following command objectName.prototype; additionally, among the properties of the prototype object is a prototype object. Is Object the same as prototype object? If not, what is Object -- the global object? How does it/they relate to the window object or global object?
Thanks in advance for your help. I've scoured the internet for an answer on this, and couldn't find one that was both accessible or understandable. Although I'm not a 10-year old, if you would kindly explain it to me as though I am, I won't be offended, and will greatly appreciate the effort.
I understand that any object that is created in JS has a hidden prototype object attached to it.
Basically yes. Every object has an internal property, denoted as [[Prototype]] in the specification, whose value is simply (a reference to) another object. That other object is the first object's prototype.
A prototype object itself is not hidden though, and you can explicitly set the prototype of an object, via Object.create:
var foo = {x: 42};
var bar = Object.create(foo);
console.log(bar.x); // 42
console.log(Object.getPrototypeOf(bar) === foo); // true
In this example, foo is the prototype of bar.
The prototype object is both a property of the parent object, and an object itself
First of all, there isn't only one prototype object. Any object can act as a prototype and there are many different prototype objects. And when we say "prototype object", we are really referring to an object that has the "role" of a prototype, not to an object of a specific "type". There is no observable difference between an object that is a prototype and one that isn't.
I'm not quite sure what you mean by "property of the parent object" here. An object is a not property, at most it can be the value of a property. In that sense, yes, an object that is a prototype must be the value of the internal [[Prototype]] property of another object.
But that is not much different than every other relationship between two objects (so nothing special). In the following example bar is an object and also assign to a property of foo:
var bar = {};
var foo = {bar: bar};
Is Object the same as prototype object?
No.
Object is (constructor) function for creating objects. var obj = new Object(); is the same as var obj = {};. However, using object literals ({...}) is more convenient which is why you are not seeing new Object used that much.
For every constructor function C, the following holds true:
Object.getPrototypeOf(new C()) === C.prototype
i.e. the value of the C.prototype property becomes the prototype of new instance of C created via new C.
Object.prototype is actually the interesting part of Object and the most important one. You may have heard about the "prototype chain". Because a prototype is just an object, it has itself a prototype, which is an object, etc. This chain has to end somewhere. Object.prototype is the value that sits at the end of basically every prototype chain.
There are many prototype chains because every value that is not a primitive value (Boolean, Number, String, Null, Undefined, Symbol) is an object (which includes functions, regular expressions, arrays, dates, etc).
If not, what is Object -- the global object?
See above. It's not the global object, the global object in browsers is window, and while every JavaScript environment must have a global objects, at least so far there is no standard way in the language to reference it (edit: I guess this in the global environment would one cross-platform way).
How does it/they relate to the window object or global object?
The only relation really is:
Object is a property of the global object, and thus a global variable.
You may think the global object's prototype is also Object.prototype, but that is not necessarily the case
Reading material:
You Don't Know JS: this & Object Prototypes ; all of gettify's books in the series are pretty awesome.
http://felix-kling.de/jsbasics/ ; shameless plug for some very concise slides that I created for a JavaScript class that I'm teaching from time to time. Might not be detailed enough to be useful on it's own (and contains typos ;) )
I'm reading that in JavaScript, a common point of confusion arises because variables of primitives are passed by value, and variables of objects are passed by reference, while in function arguments, both primitives and references are passed by value.
In the course of my tinkering, I've made up the following code, but am having trouble wrapping my head around it.
> function setName2(obj) {
... obj.name="matt";
... obj = new Object();
... obj.name="obama";
... }
If I set
var person = new Object();
person.name = "michelle";
Then run
> setName2(person);
I get
> person.name;
'matt'
Which makes sense because the new object created is a pointer to a local object, hence not affecting the property of the global 'person'.
However, what if I first set
var obj = new Object();
obj.name = "michelle";
Then run
> setName2(obj);
?
I get the same outcome. Does this mean that the compiler recognizes the two variables of the same name (obj global and obj local) as references to different locations within the heap, each having some different pointer association, or is there a different explanation for this phenomenon?
JavaScript does not have pass-by-reference; everything is passed by value. However, some values are themselves references to objects. This distinction (pass-by-reference vs. is-a-reference) leads to much confusion.
An example to clear things up:
function f(o) { ... }
var obj = { foo: 42 };
f(obj);
No matter what you do in f, obj will always refer to the same object because the argument is not passed by reference. However the value obj, which is copied into o, is itself a reference to an object. This is why any property changes made to o inside the function will be visible on obj after it returns.
while in function arguments, both primitives and references are passed by value.
This is not true. There is nothing special about function arguments.
function setName2(obj) {
This accepts a reference to an object as an argument.
obj.name="matt";
This modifies the name property of the object that reference points to.
obj = new Object();
This replaces the reference to the original object with a reference to a new object.
obj.name="obama";
This modifies the name property of the new object. The original object is unchanged.
The confusion comes from the fact that "passed by reference" is misinterpreted by people or used in a wrong sense.
Parameters are passed by value. This means that changing the value inside the method doesn't change the original value.
In case of primitives, the value of a primitive is its value.
In case of objects, the value of an object is a reference to it. You can access and change object's content but you can't change the value of the reference itself.
In other programming languages, like C++ or C#, "passing by reference" means that you pass:
- a reference to a primitive type
- a reference to a reference to an object
In such case, not only the content of an object can be changed but also a reference itself can be changed.
There is NO passing by reference in Javascript.
Javascript uses pass-by-value.
The confusion is that objects are hold by reference variables (kind of pointers). In fact most common languages (java, javascript, etc.) do not have a real pass-by-reference behaviour. Another way to understand this could be pass-reference-by-value, although, formally, there is not such a thing.
That means when you pass an object as a parameter, you are actually passing a reference to the object by-value.
function setName2(obj) {
...
}
setName2(person);
here the contents of person (a reference, or "pointer" if you like) is copied by-value to a new local variable: obj.
obj and person are different variables that hold a reference to the same object.
So, doing obj = new Object(); makes obj to point to the new object. But person is unaffected since it is still a completely different variable.
I don't know where you read that, but it's absolutely not true. Objects are passed by reference, full stop. Whether or not it's a function parameter is completely irrelevant.
Recently I read a tutorial which says if define the function like below.
function Animal() { }
On the surface, this code seems to create a function called Animal.
But with JavaScript, the full truth is slightly more complicated. What
actually happens when this code executes is that two objects are
created. The first object, called Animal, is the constructor function
itself. The second object, called Animal.prototype, has a property
called Animal.prototype.constructor, which points to Animal. Animal
has a property which points back to its prototype, Animal.prototype.
But I have little confuse about it .What about the Function object ?What is the use for the Animal object?
And If I write code like below .
var test= new Function();
and I inspected the variable test in the Developer tool of the Chrome.
I found test is nothing to do with the Function. Can someone tell me why ? thanks.
Updated
The diagram below is the objects relationship when the code is executed, please review it.
If my understanding is wrong. please correct me. thanks.
That blog post goes into a lot of detail that's interesting but unnecessarily confusing for most people most of the time.
First, let's talk about functions; forget about prototypes for a minute. When you create a function:
function Whatever() {
// ...
}
you've created an object. That is, all functions are objects, and they're constructed via the Function built-in constructor. The symbol "Whatever" in this example will have as its value a reference to that object.
Given a reference to a function, it's possible to call it:
Whatever(); // call the function
It's possible to take that value (the reference to the function object) and assign it to another variable, or pass it as a parameter to another function, or to use it just like any other value in JavaScript.
var another = Whatever;
another(); // also calls the "Whatever" function
Constructing a function via the Function constructor explicitly is something that's rarely done, but it gives you a function that's otherwise unremarkable. (In the OP, the constructed function doesn't do anything because no code was passed to the Function constructor.)
Now, things get interesting when a function is invoked as part of a new expression.
var test = new Whatever();
By using new, a new object is instantiated and associated with the "Whatever" function. The "Whatever" function is the constructor for that new object.
Every function object, whether it's ever used as a constructor or not, has an associated "prototype" object. When a function is used as a constructor, then objects it constructs (that is, objects made in new expressions that invoke the function) are implicitly associated with that prototype object.
The prototype object becomes interesting when an object property reference expression is evaluated. Object property references look like this:
obj.name
obj[ nameExpression ]
In such an expression, the property name (either the identifier used in the . expression or the value of the expression inside [ ]) is checked against the set of properties on the object directly. If the name is not the same as one of the object's properties, then the runtime consults the prototype object associated with the constructor function used to make the object.
For most code that most people write, that relationship and some of its direct implications are the only things to worry about. You don't have to fool around with the (non-standard, at this time) "proto" property of objects unless you're putting together some sort of library or framework.
Finally, it might be instructive to look at the Object.create() function and in particular the "polyfill" shown in that documentation.
Javascript copies objects by reference, rather than literally. For example:
var myObject = {};
var myCopy = myObject;
myObject.foo = "bar";
alert(myCopy.foo); //alerts "bar"
But I am really struggling to think of practical, real world reason for this other than giving developers a way to make code slightly more readable (as you can give different uses for the same object different names).
The most likely thing is I have missed the point, so can anyone tell me what that point is?
After writing:
var myObject = {};
There is an object out in memory somewhere that you can refer to by the name myObject. The following assignment:
var myCopy = myObject;
...says that myCopy now refers to that same object, wherever it may be. This is the same thing that happens when you give an argument to a function:
function somefunc(localName) {
// body
}
someFunc(myCopy);
Now there is a variable called localName that is local to someFunc that also refers to that same object out in memory.
This is the fundamental way in which we pass around references to an object, so that it can be referred to by different names, in different scopes.
We could copy the entire structure into a new location in memory. There was nothing stopping the designers from creating a language that did that. But it's less efficient -- think of deeply nested objects -- and generally not what you want to do. For example, if a function modified one property of an object, it would need to return the entire object for that change to persist outside of the function. And the caller would need to handle that return value, deciding whether the old object needs to be kept or if the newly created, slightly different copy can overwrite it.
Again, there's nothing wrong with this design direction in principle; it's just not how JavaScript was designed.
It depends; in your case it might be rather confusing since it doesn't serve a real purpose. However, for longer paths to the object it can be advantageous to store the object in a separate variable, because it requires less typing for each statement that uses the object, such as in this example:
var style = document.getElementById("foo").style;
style.color = "red";
style.font = "sans-serif";
// ...
My opinion (and it's nothing more than that) is that creating an object by reference (rather than copy) is generally more useful and what the user wants. If you pass an object as a param to a method, you're (almost always) interested in the object being worked on and altered by that method, rather than by working on a copy (and leaving the original untouched). Obviously there are circumstances where this is not true and it would be nice to have the option to choose, but I've can't recall ever finding myself wishing that I could just pass an object copy to a method, and am usually very grateful that the thing I'm working with is THE thing.
Coming from C++ it is hard grained into my mind that everytime I call new I call delete. In JavaScript I find myself calling new occasionally in my code but (hoping) the garbage collection functionality in the browser will take care of the mess for me.
I don't like this - is there a delete method in JavaScript and is how I use it different from in C++?
Thanks.
var component = new Component();
component = null; // delete this at next garbage collection
Incidentally, the "new" keyword isn't really necessary in javascript, and has nothing (directly) to do with allocating memory. All "new" does is pass a new, empty object called "this" (this = {}) as a hidden argument to the function.
var MyClass = function(){
// fresh empty object "this" gets passed to function
// when you use the "new" keyword
this.method = function(){}
}
var myInstance = new MyClass();
Javascript can get kind of hairy with nested closures and multiple "this" variables floating around in different scopes. I prefer to do it this way:
var MyNoNewClass = function(){
// I find this more explicit and less confusing
var self = {}
self.method = function(){}
return self;
}
var myNoNewInstance = MyNoNewClass()
All JavaScript memory is referenced, but not in the traditional sense. Memory is referenced not by memory address but by a string. In this code:
var x = new someObj();
That object is referenced by the string "x" from that point forward. x is not a pointer to some memory on the heap at that point. If you assigned x a property then:
x.someProp = 42;
Then someProp is a string in memory referencing the value 42. Consequently that lets you use array notation to access it by it's string representation:
x["someProp"]++;
It's also why variables can hold any value as they don't have need of size.
Memory is collected in JavaScript, effectively, when no more strings (aka variables or property names) are referencing it. That object will be collected when x is assigned any other value. You could set it to null, undefined, or anything else and that memory will be collected.
That is, it will be collected when the browser or whatever JavaScript engine gets around to it.
Delete only removes properties from objects. From then on attempting to access that property will return undefined. For the most part, the following 2 lines of code are equivalent:
x["someProp"] = undefined;
delete x.someProp;
Edit: Ok, internally the two lines aren't the same. The delete operator will remove the "someProp" reference from memory, while setting it to undefined won't. I think. I can't find anything in the specs about setting a variable or property to undefined, but I don't think doing so does anything special.
The important thing to note is that you won't be able to delete properties that have a certain flag set, but you can set them to null or undefined (if they're not wrapped by a setter and even allow that to happen).
Taken outside of the context (the browser) the javascript is fully capable of reclaiming the memory through garbage collection. Going back to reality garbage collection in combination with DOM model can cause memory leaks.
Here is one article http://www.ibm.com/developerworks/web/library/wa-memleak/ you can find more details about it
To avoid memory leaks
Ensure you remove all event handlers, so if you add like a mouse down event handler ensure you remove it when you finish
if you add elements to the DOM, remove them when done
if you have an object that points to another object, remove the reference when the object is done with.
when you are finish with any object set it to null.
deletes just gonna remove a property from an object.
There is a delete. However, an actual need for it will be rare. It's not like C++ delete, though.
delete in JavaScript will remove a property from an object. Subsequent accesses of that property will return undefined. I assume it will be able to free any associated memory on subsequent garbage collects.
Don't use delete in JavaScript unless you are removing event handlers. Even then, we only do this because there is a memory leak associated with this practice in older versions of IE. Douglas Crockford explains this pretty well. In his case, he doesn't even use delete. He simply sets the values in question to null.
From the MDC:
The delete operator deletes a property of an object, or an element at a specified index in an array.
The delete operator in my opinion is only useful when you want to remove a property from an object. But since there might be other references to the property that it were referencing, it wont be really GCed. If you want something to be GCed, you need to remove all pointers pointing at it and also free the closures containing references to it (more info on the topic).
new creates objects from a constructor. delete removes properties from an object. These are two very different things.
You don't have to delete objects you created. The GC takes care of this.
delete o.fu is different from o.fu = undefined. Try this:
var o = {};
alert(o.hasOwnProperty('fu')); // -> false
o.fu = undefined;
alert(o.hasOwnProperty('fu')); // -> true
delete o.fu;
alert(o.hasOwnProperty('fu')); // -> false
There is a delete in Javascript, but trust me: it's way different than delete in something like C++. I recommend you don't even think about using it until you're more comfortable with Javascript.
Garbage collection works, though it doesn't defeat the problem of memory leaks.
The "new" keyword has nothing to do with memory. It's purpose is only to setup the prototype chain.
// C++
Foo* foo = new Foo(); // allocate and construct
// JS "sugar" using the new keyword
var foo = new Foo(); // allocate and construct
assert(foo instanceof Foo);
// JS constructing objects without "new"
var foo = Object.create(Foo.prototype); // allocate with prototype
Foo.call(foo); // construct
assert(foo instanceof Foo);
// construct Foo with missing prototype
var foo = {}; // allocate without prototype
Foo.call(foo); // construct without prototype
assert(!(foo instanceof Foo));
// so the corollary operations in JS are
foo = {};
foo = null;
// where-as this is an error (or most certainly not what you want)
delete foo;
// and this is how delete is used
foo = {bar: 42};
assert(foo.bar === 42);
delete foo.bar;
assert(foo.bar === undefined);
// but by deleting a property, you remove the reference to the object
foo = {bar: {baz: 31}};
delete foo.bar; // remove only reference to "bar" object
// JS GC will now take over
So no, you can't delete objects. But you can delete references to objects, which may trigger object deletion by the GC. But of course, local variables (and global) can't be deleted. They simply go out of scope, de-referencing any associated objects, and potentially freeing memory, but only if the object wasn't returned or is still referenced elsewhere.
It's important to realize that because JS doesn't support pointers, GC can be perfect. At any point, the GC can simply walk the entire set of objects "seen" from any in-scope function and guarantee it doesn't miss anything like cycles, etc.
As long as you use JS in a functional style and don't try to build global god objects which tie everything together, memory management should be a non-issue.