I was learning about constructors, and I came across the new keyword.
var obj = new myContructor();
I learnt that it created a new object, set its prototype as constructor.prototype, set its properties as according with the this keyword, and finally returns that object.
Now, I am confused as to where exactly does it create the new object, as inside memory or somewhere where it is volatile.
And what do we mean when saying it RETURNS that object, that it creates a copy of the new object at the location of the var obj, or does it reference obj to wherever it created the new object ?
inside memory or somewhere where it is volatile
Yes, of course. Just like any other piece of data in the program.
do we mean when saying it RETURNS that object
You are making a function call. Function calls have return values. The object is the return value of that function call.
it creates a copy of the new object at the location of the var obj
It creates it in the function, then it returns a reference to it (just like any other object), and that reference is stored in the variable because you used an assignment.
There are many things going in behind the scenes in Javascript; things are constantly being created in memory that you do not have access to. As far as you are concerned with this while writing Javascript code:
new creates an object and does all the prototype stuff
myConstructor() is executed, and this inside the function is set to that object
(put another way: myContructor is called with the object as context)
after myConstructor is done, the object is assigned to the variable obj as result of all this
There are a bunch of caveats regarding what myConstructor can return and how that influences the result, but we'll ignore that for simplicity. The basic chain of events is new creates object → myConstructor sees that object as this → obj "receives" this object as return value of new.
Of course, all this creating of the object and passing it around to different places is done by the Javascript engine, and requires internal storage of the object somewhere in memory.
Related
I'm trying to some how understand what happens inside a closure and use the variables and functions created inside of it.
My limitation is that I can add as many lines of code I want to the existing closure, but cannot edit any existing ones.
Can this be done?
<script>
var scopeClone = {};
(function(scopeClone){
//Activation Object {}
scopeClone.a = "a";
var b = "b"
//Activation Object {b:"b"}
//my custom code here
//We want to copy activation object properties to scope obj
})(scope);
//At this stage, we want to get -> scopeClone.b = "b"
</script>
Not sure it can be done:
http://interglacial.com/javascript_spec/a-10.html
10.1.6 Activation Object
The activation object is purely a specification mechanism. It is impossible for an ECMAScript program to access the activation object. It can access members of the activation object, but not the activation object itself. When the call operation is applied to a Reference value whose base object is an activation object, null is used as the this value of the call.
And from here as well:
https://www.reddit.com/r/javascript/comments/2tdwcv/are_there_any_backdoor_ways_to_access_the/
Note that Activation object is an internal mechanism and is never really accessible by program code.
I know that local variables dosent work when testing it, but I dont understand the concept. Why does "this" work and local variables does not? a clarification would be great on why I must use this and avoid local variables!
code:
function Person(job, married) {
var employ = job;
var status = married;
}
var ray = new Person("student", true);
console.log(ray);
You can use local variables in your constructor, but they don't automatically become instance variables of your object. Instead, the way you are using them, they are just temporal local variables, like local variables inside any function definition.
When you do this:
function Person(job, married) {
var employ = job;
var status = married;
}
var ray = new Person("student", true);
Here's what is happening:
You define a function named Person.
In that function, you define two local variables named employ and status.
Those are normal local variables within a function. They are only visible to code within that function. These may be useful for some things, but they are not available to any code outside that function. They are not available to prototyped methods of your object, they are not available to other code outside that function. In fact, without some sort of reference that creates a closure, they have a limited lifetime and are gone and garbage collected as soon as the Person function finishes executing.
So, if you intended to create the C++ equivalent of member variables of your object, this did not accomplish that. The variables are used only for the duration of the Person() function and are then disposed of and have no lasting presence.
Then, when you execute var ray = new Person("student", true);, the following things happen.
The new causes the system to create a new object, set the value of this to point to that new object and then call the Person constructor with your two arguments.
Your code then creates two local variables which you assign the two arguments to.
The Person() function then finishes executing and the two local variables are disposed of because the scope in which they were defined is done and is garbage collected.
You then assign the newly created object to the variable ray. It is indeed a new object, but it has no custom instance data because nothing was stored in a lasting way.
If you then do console.log(ray), you're just going to see an empty object with no instance data other than what the default Object instance has. Your custom data was not stored anywhere lasting so it's gone now.
If you intend for those two arguments to be saved somewhere lasting as instance data of the object, you have a couple choices. The more traditional choice is to make them publicly accessible properties of the object. You would do that like this:
function Person(job, married) {
this.employ = job;
this.status = married;
}
Since this points to the newly created object, this code assigns the job and married arguments to properties of the newly created object. These properties can be accessed either by other methods on the object or by any code outside of the constructor like this:
var ray = new Person("student", true);
console.log(ray.employ); // "student"
console.log(ray.status); // true
These properties are publicly accessible.
There are some interesting things you can do with those local variables that can allow them to persist and be used after the object is created. To do that, you have to create a closure. I think of a closure as a function scope that would normally be discarded when the function finishes executing, but because of circumstances, there are still live references within the function scope so the garbage collector does not throw away the function scope when the function finishes executing like it would in a purely stack based language like C++. Instead, it persists and can be accessed by code after the object has been created. Here's an example:
function Person(job, married) {
var employ = job;
var status = married;
this.getEmploy = function() {
return employ;
}
this.getStatus = function() {
return status;
}
}
var ray = new Person("student", true);
console.log(ray.getEmploy()); // "student"
console.log(ray.getStatus()); // true
Here's the assignment of functions within the constructor has created a closure. The private local variables employ and status are still private to within the scope of the Person function. But, because the getEmploy and getStatus properties are now publicly exposed and can be called at some time in the future and those functions reference the employ and status variables, the garbage collector realizes that it can't garbage collect the employ and status variables so they persist for the lifetime of this newly created Person object.
Using terms familiar to other object oriented languages like C++, the employ and status local variables are giving you some of the features of private instance variables. Some people call this a hack to fill the void of a feature that Javascript does not offer quite so directly. But, I don't see it as a hack. The language offers closures as an enormously useful feature that can be used in so many ways and this is just one way of using a closure to create a benefit, the benefit of private instance data.
Only the publicly assigned properties getEmploy and getStatus can be accessed by the outside world, but by calling them, we can access the private variables employ and status. If we do console.log(ray) in this new model, we still won't see employ and status there because as far as the console is concerned, they still aren't properties of the ray object. But, because of closures, they are uniquely accessible by the methods on the ray object.
Further, because a new closure is created each time we call the Person constructor, these employ and status variables are uniquely associated with each new instance of the Person object. They behave and work like private members of the object.
For more examples of this type of structure and some more explanation, see this classic discussion: http://javascript.crockford.com/private.html
Why does "this" work and local variables does not?
Unless some sort of lasting closure is created, local variables are temporal. They last only as long as the containing function is executing and they are then garbage collected. Just because they are declared inside a function that you are using as a constructor does not make them special. They are just local variables and have no magic powers beyond just being local variables.
In a class constructor why is “this required”?
a clarification would be great on why I must use this and avoid local
variables!
If you want to assign properties to your object, it is this that points to your object in the constructor so the only way to assign to a property of your object is to reference the object as this.someProperty = xxxx. That's just how the language works. All property references in Javascript require an object as the first part of the access. And, in a constructor, the reference for the newly created object is this. That's how the language was designed.
Those coming from some other object oriented languages might thing you can declare an instance variable of a class and then just use that name all by itself and the interpreter will somehow just know that it's an instance variable name, not a variable name. That might be true in some other languages. That is not true in Javascript. All property references, whether in the constructor, in some method or accessed from the outside as a property on an object must all use an object as the base of the reference. And, inside the constructor and inside a method, that base is the value of this. So, this.someProperty is how you reference that property on the current instance.
Think of it like this:
A class is basically an object, right? Well, when you declare a new instance of Person, you're saying "let's create a new object with properties x, y, and z." Using "this" allows you to access the properties for that instance later, while local variables aren't treated as properties for your object.
When a function is called as a constructor (using the new keyword), a new object is created (the instance object), prototyped on the object value of the function's prototype property, and the constructor called with its this value set to the new instance object just created.
Constructor code can set properties and methods on this (the instance object), which is the return value of the constructor call (... unless the constructor explicitly returns some other object).
If variables defined within the constructor are accessed by nested functions which persist after the contructor returns, they will not be garbage collected because they can still be accessed. If they are not accessible after the constructor returns they are essentially discarded and become available for garbage collection.
Object creation is fundamental to JavaScript behavior: Try looking up and reading about the use of constructor functions.
More about retention of variables in the scope of nested functions after an outer function exits can be found by searching for "closures in JavaScript".
I was always taught that in Javascript there is no distinction between objects and classes. Then can someone explain why this code generate error:
var firstObj = function() {};
firstObj.prototype.sayHi = function() {
document.write("Hi!");
};
firstObj.sayHi();
Whereas this one works:
var firstObj = function() {};
firstObj.prototype.sayHi = function() {
document.write("Hi!");
};
new firstObj().sayHi();
What's the difference? Why isn't the first one working?
The key issue here is that your firstObj variable is a Function object, not a firstObj object. This is a subtle distinction, but the type of object determines which prototype it inherits.
The prototype is like a template that is applied to newly created objects of a particular type. You must create a firstObj object (usually with new which invokes the constructor and assigns a prototype) in order to have that template applied to it. In the first example, your firstObj variable is a Function object, not a firstObj object so it has the prototype of a Function not of anything else..
In your second example, you actually create a firstObj object so it inherits the prototype for that type of object.
If you want the method applied in your first example so it works on the function object you've already created, just put the method directly on your already existing function object, not on the prototype.
There is no difference in the language between objects and classes1. However, there is a big difference between one kind of object and another. In the first case:
firstObj.sayHi();
you are trying to access the sayHi property of firstObj, which is a Function object that does not have such a property. (You could, however, do firstObj.prototype.sayHi().)
In the second case:
new firstObj().sayHi();
you are first invoking the new operator on the firstObj object, which evaluates to a new object. That new object has firstObj as it's constructor property and a prototype equal to the prototype property of firstObj. You are then accessing the sayHi property of that returned object, which succeeds because sayHi is in the prototype chain for that object.
1 Technically, JavaScript doesn't have classes2 (in the traditional sense), just constructor functions that are usually called "classes".
2 However, class is a future reserved word.
when you write this:
var firstObj = function() {};
you only define a constructor function, thus you need to use the key word new for the new objects created with this constructor function.
A function is just a function until new is issued. At that point, a Function Object is created based on the prototype for the function. That is why you will not see the sayHi method present in the first version.
Also, firstObj is a function, and not an object, so you need to invoke it to actually have anything happen. firstObj will not actually invoke the function, you must use firstObj().
Further, there are ways to have the prototype used without explicitly requiring the new keyword. This is done in a number of popular frameworks (such as jQuery). It is done by checking to see if new was used, and if it was not, then it news one up for you on the spot:
jsFiddle Demo
var firstObj = function() {
if( !(this instanceof firstObj) ){
return new firstObj();
}
};
firstObj.prototype.sayHi = function() {
alert("hi");
};
firstObj().sayHi();
In the context of inside a function, here's the code (based on the standard pattern of making a function's 'arguments' into an array):
var args = Array.prototype.slice.call(arguments);
I'm trying to study this out (am a beginner at JavaScript, coming from C#).
I understand that slice is an instance method due to it being a prototype function of Array.
I also understand that this is not a static 'utility function', meaning to use it, you have to new it up like so: (example) var myArray = new Array(); myArray.slice(...);
call passes an object in here to change the context to that of arguments
Related to this, I don't also know the difference between
Array.prototype.slice.call([32,32,121,412]) and Array.prototype.slice([32,32,121,412]) not in the context of call.
So, here's my question:
I just don't get how this works in relation to instance vs static methods... so can anyone explain the intricacies of var args = Array.prototype.slice.call(arguments);?
Why can this be used without calling new?
Why was this possible? It's not a Static method, and it must be 'newed' up, and it only works when you use call function... (at least in my C# mentality...)
The difference between Array.prototype.slice.call([32, 32, 121, 412]) and Array.prototype.slice([32, 32, 121, 412]) is that in the first case, the actual Array [32, 32, 121, 412] becomes the "this" object for the call. In other words, it's just like this code: [32, 32, 121, 412].slice(). Just calling slice on the prototype executes it in the context of the prototype object, which probably wouldn't do anything useful.
When you add a function to an object's prototype, it becomes a function that you can use on instances of that object. The context of that function with be the instance. i.e.
Array.prototype.myFunction = function() {
alert( this[0] ); // this should refer to the Array instance
};
var x = new Array(1);
x[0] = 5;
x.myFunction(); // alerts 5
However, sometimes you may have a structure like an array that are not a subclass or instance of Array (such as an Arguments object). What the call method of a function does is changes the context to whatever the first parameter to call is. In this case, the call method is being called on a function of the Array's prototype. In all reality, Array.prototype.myFunction is just a function defined in the above block of code. call is a method that can be called on any function to change its context. Therefore, instead of an Array instance as the context, you would have an arguments object.
function foo() {
Array.prototype.myFunction.call( arguments ); // arguments is [6]
// alerts 6
}
foo( 6 );
More info on call.
I think perhaps you're getting confused by the behaviour of "instance" and "static" methods in languages like Java that have classes. JavaScript doesn't work the same way.
Also you're confused about another issue, that being how all JS function calls work in terms of setting this within the called function (i.e., setting what object the function will likely attempt to operate on) and what effect .call() has on setting this.
The .slice() method is defined as a property of Array.prototype, not as a Java-style "instance method" on the individual array instances. You can call Array.prototype.slice() without needing an instance of an array created with new.
When you say:
myArray.slice()
JS will first see if .slice() actually is a method of the myArray object, and then (given that it isn't) it will see if it is a method of the Array prototype - which it is, so it runs that method.
When you call any JS function with "dot" notation, i.e., myArray.slice(), within that function the special variable this will be set to the object. this is a reference to the object that the function should operate on. But if you call a JS function using .call(), within that function this will be set to the object you pass as a parameter to .call(). So
myArray.slice()
says to call .slice() and have it operate on myArray.
var args = Array.prototype.slice.call(arguments);
Says to call .slice() and have it operate on arguments
P.S. don't use var myArray = new Array(); - better to say var myArray = [];
Unlike C#/Java, functions are actually first-class citizens in JavaScript.
In a general sense:
This means there is no need to "new" it up.. it works exactly as it is because it is its own object.
"new"ing up a function (in a general sense) merely changes the 'this' value of that function to the variable it will be assigned to, then returns it.
It is possible to use a function in JavaScript without "newing" it up because they are "first-class citizens" in JavaScript.
In a more in-depth sense, this is what "new" does:
- it creates a new object deriving from MyConstructor.prototype
- it assigns the 'this' value of the constructor function to the new object
- execute the code inside (adds properties to new object/instance)
- returns the new object
Some extra notes about what I learned from instances:
- they don't have a .prototype property like their constructor functions
- though they have a [[prototype]] property, derived from MyConstructor.prototype
- overriding a property in the instance shadows the MyConstructor.prototype[property]..
Hello I'm a newcomerin JavaScript language.
I started to see some examples of JavaScript code.
and i cant understand the following code segment:
function Employee(name,salary)
{
this.name=name;
this.salary=salary;
this.paycheck=function()
{
var monthly=this.salary/12;
document.write(this.name+ ": " +monthly);
};
}
var emp= new Employee("Fred",10000);
emp.paycheck();
My question: what is the meaning of word this near the property inside class (i.e. ,this.name=name; this.salary=salary; )?
Thank you in advance!
The use of this could be explained as meaning "properties that apply to this instance". Since Employee is a constructor function (you create instances of it using the new operator), every instance has its own values for those properties:
var me = new Employee("James", 2000000); //Instance of Employee
console.log(me.name); //Prints James
var you = new Employee("Michael", 2000000); //Another instance
console.log(you.name); //Prints Michael
Note that this also means every instance of Employee has its own copy of the paycheck method. This is not particularly efficient, as a separate copy of the function has to be stored in memory for every instance of the object. You could instead declare the method on the prototype of the Employee object, which would mean the method would be shared between all instances.
In JavaScript this always refers to the “owner” of the function we're
executing, or rather, to the object that a function is a method of.
When we define our faithful function doSomething() in a page, its
owner is the page, or rather, the window object (or global object) of
JavaScript. An onclick property, though, is owned by the HTML element
it belongs to.
For further reading see these links:
http://www.quirksmode.org/js/this.html
http://justin.harmonize.fm/index.php/2009/09/an-introduction-to-javascripts-this/
http://javascriptweblog.wordpress.com/2010/08/30/understanding-javascripts-this/
this is a reference to the calling context of the function.
Its value will be different based on how a function is invoked.
In your case, because Employee is invoked using new, it's a reference to the new object being constructed.
So when you do...
this.name=name;
...what's happening is that the new object you're creating is being assigned a property name, and its value is being set to whatever was passed to the name parameter of the function.
Here's one way to demonstrate it.
Simplify your function like this...
var foo;
function Employee() {
foo = this;
}
So now all Employee does is set its this value to the outer variable foo.
Now lets create a new object
var bar = new Employee();
So bar has been assigned whatever Employee returned. If this is the new object constructed, and we assigned it to foo, then foo and bar should have the same object.
foo === bar; // true
In this case the Employee function is used a constructor. When the new Employee() syntax is used (as opposed to simply calling Employee()), this refers to an object that you are about to create, which is later assigned to emp variable.
it's a definition of properties inside the class.
You can read short information about it here http://www.phpied.com/3-ways-to-define-a-javascript-class/
this always refers to the “owner” of the function we're executing