Possible Duplicate:
Javascript: Do I need to put this.var for every variable in an object?
I'm struggling to understand functions and objects in javascript. It is said that also functions are objects and objects are kind of "associative arrays" i.e. collections of key-value pairs. I understand that if I write
function myFunction() {
var value = 0;
}
alert(myFunction.value); //then this gives me "undefined"
because variables have function scope. But if I write
function myFunction() {
this.value = 0;
}
alert(myFunction.value); //then this gives me "undefined" too.
But finally, If I write
function myFunction() {
this.value = 0;
}
myFunction.value = 0;
alert(myFunction.value); //then this gives me 0
So I can give myFunction property "value" but from "outside". Can someone explain what is going on and why this.value = 0; doesnt create property "value".
The javaScript, generally, we have used some default method/function to achieve. The goal for these types of concepts is called cloning the object, but each and every function has its own attributes and properties in the script.
Object. assign does not copy prototype properties and methods. This method does not create a deep copy of Source Object, it makes a shallow copy of the data. For the properties containing reference or complex data, the reference is copied to the destination object, instead of creating a separate object.
Cloning a JavaScript object is a task that is used mostly because we do not want to create the same object if the same object already exists. There are few ways. By iterate through each property and copy them to new object. Using JSON method as the source object MUST be JSON safe.
JavaScript provides 3 good ways to clone objects: using spread operator, rest operator and Object. assign() function. Aside from just cloning objects, using object spread and Object. assign() lets you add or updated properties when creating the clone.
You need to create a instance
by using the new keyword.
function myFunction() {
this.value = 0;
}
var inst1 = new myFunction();
alert(inst1.value); // this works
Now this corresponds to the current object , and it gets you the corresponding value of the property.
Check Fiddle
At end of the day .. functions are still objects.. So it does not complain when you assign myFunction.value = 0
.. It might be confusing as you are using the value (key) both inside and outside the function..
Replace it with
myFunction.abc = 'Hello'
alert(myFunction.abc) still works
But it won't be reflected inside the actual myFunction as you have not called the function yet.
Let's look at all three cases individually:
function myFunction()
{
var value = 0;
}
Here, you're declaring a variable in the function's scope. Each time the function is called, the variable will be created (and memory will be allocated). When the function returns, the variable goes out of scope - the variable value
is flagged and will be GC'ed. The scope can't be accessed from a scope "higher" than this function's scope... if this function defined a function within its scope, that function will have access to the variable value
(look into closures for more details). Bottom line: the variable only exists as when the function is called, and won't exist after the function returns.
function myFunction()
{
this.value = 0;
}
Here, you're defining a function that could be a constructor, a method, an event handler or a combination of all of the above. this
is a reference that will point to the context in which the function is called. This contexted is determined "ad hoc" and may vary:
myFunction();// global scope, this points to window
var anObject = {method: myFunction};
anObject.method();//called in the object's context, this points to object
console.log(abObject.value);//logs 0
var instance = new myFunction();//as constructor
console.log(instance.value);//logs 0
document.getElementById('anInputField').onclick = myFunction;//on click, value will be set to 0
In the last case:
function myFunction()
{
this.value = 0;
}
myFunction.value = 0;
It wouldn't have made any difference if you'd have written this:
function myFunction()
{}
myFunction.value = 0;
Because, as I explained above: this
references whatever the context is at the time the function is called. This needn't be myFunction
, in fact: more often than not it won't be:
var anObject = {method: myFunction};
myFunction.value = 101;//myFunction.value is changed
anObject.method();
console.log(anObject.value);//0 -> the function still sets the value property to 0
If you want to access a function's properties inside that function, the easiest way is to reference that function like any other object:
function myFunction()
{
this.value = myFunction.value;
}
myFunction.value = 101;
Caution:
Just a friendly warning: it's not very safe to use this
in functions without checking for globals... If a function is called without an explicit context, JS uses the global (window
) object by default. This means that every line that assigns a property to whatever object this
happens to be pointing too will set a global variable:
function myFunction()
{
this.foo = 'bar';
}
myFunction();
console.log(window.foo);//logs bar EVIL GLOBAL
A few ways to prevent the global object from being cluttered with globals:
function mySafeFunction()
{
'use strict';//throws errors, check MDN
//this defaults to null, instead of window
impliedGlobal = 'Error';//doesn't work
this.onGlobal = 'Error';//null.property doesn't work
}
//same goes for constructors, but a more precise check can be used, too (and works on older browsers)
function SafeConstructor()
{
if (!(this instanceof SafeConstructor))
{//this doesn't point to SafeConstructor if new keyword wasn't used
throw new Error('Constructor wasn\'t called with new keyword');
//or "correct" the error:
return new SafeConstructor();
}
console.log(this);// will always point to the SafeConstructor object
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With