Names of Objects properties vs Constructor function arguments in JavaScript - javascript

First of all, I apologize if this question is too basic or not worded correctly. I'm learning JavaScript and I'm still new to it. And I've been trying to figure out an example that is included in a textbook, and need some help.
This is the example:
var star = new Object;
function Star(constell, type, specclass, magnitude) {
this.constellation = constell;
this.type = type;
this.spectralClass = specclass;
this.mag = magnitude;
}
star["Polaris"] = new Star("Ursa Minor", "Double", "F7", 2.0);
alert(star["Polaris"].spectralClass);
The part that I don't get here (and can't seem to find an explanation) is that when I pick a random object to alert such as
alert(star["Polaris"].spectralClass);
I have to use the name inside a function aka spectralClass and not specclass. Why is that? Why not just use specclass if I already assigned it to spectralClass? I'm missing a huge chunk of knowledge here, I assume, but I just can't seem to figure out what it is.
Thank you!

Let's simplify the code even further:
function Star(specclass) {
this.spectralClass = specclass;
}
Here, Star is a constructor function. It takes one argument, which can be referred to via the name specclass inside the function.
The function assigns this argument value to the object's property named spectralClass.
Now,
var polarisStar = new Star("F7");
polarisStar is the object constructed by the Star function, which has assigned the value of "F7" to the object's spectralClass property. So you can access it via polarisStar.spectralClass, e.g.
alert(polarisStar.spectralClass);
Actually, it's a common practice to give constructor's arguments and constructed object's properties the same name, i.e.:
function Star(spectralClass) {
this.spectralClass = spectralClass;
}
This makes the code it a little bit more readable.

specclass is a local variable inside the constructor function.
spectralClass is the name of the property exposed by the constructor.

The fact that:
this.spectralClass
is in the constructor makes the variable available to that objects instance... So you can access it in other functions within the class.
On the other hand,
specclass
Is only local to the constructor function.

Related

JavaScript constructor parameter or this.property

Can somebody explain the difference?
function Constr(name){
this.firstname=name;
this.log=function(){
console.log(this.firstname);}
}
And
function Constr(name){
this.firstname=name;
this.log=function(){
console.log(name);}
}
Is there a difference using the property or the argument?
Many Thankd
Greetings
KAT
The local variable (constructor parameter) cannot be changed from outside. The property value can.
const obj = new Constr("a");
obj.log();
obj.firstname = "b";
obj.log();
Compare how the two versions behave differently in the above snippet. Btw, you also should avoid creating methods in the constructor but rather define them on the the prototype, which makes it impossible for them to access local variables from the constructor scope. See also Javascript: Do I need to put this.var for every variable in an object?.

constructor function: something related to an instance or something related to a class?

What should I put into a constructor function: something related to an instance or something related to a class?
Consider this code:
var count = 0
TView = function (x, y) { this.x = x, this.y = y, this.id = count++ }
TGroup = function() {}
TGroup.prototype = new TView
var v1 = new TView(1, 1)
var g1 = new TGroup(2, 2)
console.log(count, v1.id, g1.id, g1.x, g1.y)
output:
2 1 0 undefined undefined
here new TView happens twice... Once when I really need to create a TView instance, other time when I assign a TGroup prototype. Hence my question.
The problem here is that your constructor's arguments are not passed from TGroup's constructor to TView's constructor... And don't bother adding "super(x, y)" or whatever similar call, it won't work: constructors in JavaScripts "objects" are not so much "object-oriented".
Disclaimer: descriptions in the following paragraphs contains some statements that are not exactly true, in order to make the key concepts easier to understand. Please refer to comments bellow for clarifications and rectifications.
A better way to think about it is that an object in JavaScript is basically an hash map, containing both regular values (that are the object's fields) and functions (that are the methods). The class is also a map (well, it is a function, but JavaScript is somewhat lousy on these...), which usually contains a single method and maybe some values. Now one of these values stores on the "class" map is the special "prototype" map.
When a new "instance" map is created by using the new operator on the "class" object, three things happens: first, a new map is created; then, every key-values that existed in the class map prototype array is copied to the newly created map, along with the constructor method; finally the constructor method is invoked, with the arguments that were given.
So you should by know understand why, in your example, you need to create a new instance of TView to be passed to TGroup.prototype. It means that when creating new instances of TGroup, they will first copy everything that was in that first object you created there. Noticed that your TGroup has id 0? That's because the TGroup copied the id of the first TView that was ever created. No matter how many TGroup you create, they will all have id 0. The goes for your x and y arguments: its the one you gave when setting TGroup's prototype that will be kept, no matter what you give in input to TView.
Note that there are other issues related to this approach. Most importantly, you can't simply override a parent method, then call your super's original version.
Now, what are the solutions? Well there are a few, actually. One of them could be to use the most recent features for ECMA Script objects, but I won't go there. There are also some JavaScript libraries that offer a more "object-oriented" strategies.
The most simple strategy, though, might simply to follow a simple idiom, that is to add an init_class name here method inside each instance prototype, then have your constructor invoke that init_() method; then, each init_() method should explicitly invoke it's parent init_*() method, passing whatever arguments that need to be given.
You should not create an instance of Parent to set the prototype part of inheritance because instance specific members of the Parent will be shared (instance of Parent is Child.prototype).
Your Child class does not re use Parent constructor code and initialises instance specific members (this.something, this.somethingElse).
When inheriting through prototype and constructor functions it may be better to pass one object instead of separate parameters.
A more detailed explanation about these three you can find here.

Is "this" necessary in javascript apart from variable definition

My question is dead simple.
I just casually discovered that once you have defined a property with this. into an object, you don't need to prepend this. anymore when you want to call them.
So this. is really meant to be used ad definition time, like var?
I found it my self shortly after, i was referencing the window object with this. since i called my object without using new, so like it was a function.
One extra question, maybe for comments. Inside the main object, if i create a new object, and use this during the object definition, this this what will be referring to?
No, unless the context of this is a global object, such as window. Take the following example:
function Foo(bar) {
this.data = bar;
console.log(this.data); // OK
console.log(data); // ReferenceError
}
In this example, you'll get a ReferenceError: data is not defined on the first console.log(data), unless, data is a global variable. To access the instance's public member, you have to use this.data.
References:
Understanding JavaScript’s this keyword
The this keyword
There are all sorts of circumstances where you MUST use this in order to reference the right data.
These two implementations do very different things:
Array.prototype.truncate(newLen) {
// sets the length property on the current Array object
this.length = newLen;
}
Array.prototype.truncate(newLen) {
// sets a global variable named length
length = newLen;
}
var arr = [1,2,3,4,5,6,7];
arr.truncate(2);
You MUST use this in order to control what happens if you want to modify the current object. Your assumption that you can leave it off and it will still modify the current object's properties is not correct. If you leave it off, you are modifying global variables, not member properties.
So this. is really meant to be used ad definition time, like var?
No, the point of this is to be the current scope of execution. You can (and will) run into weird errors if you don't use this. For example, imagine you are an object with a property val and then on the prototype of that object you have
App.obj = function(){
this.val = 'initial';
}
obj.prototype.myMethod = function(val) {
// how would you assign argument val to object val?
}
also note that your reasoning breaks down with methods.
obj.prototype.meth2 = function(){
myMethod(); // fails where this.myMethod() would work.
}
See http://jsfiddle.net/BRsqH/:
function f(){
this.public='hello!';
var hidden='TOP SECRET!';
}
var instance=new f();
alert('Public data: '+instance.public+ /* gives "hello!" */
'\nHidden data: '+instance.hidden /* gives undefined */
);
Variables created with var are hidden and cannot be viewed nor modified outside the function which created them.
But variables created with this are public, so you can access them outside the function.
I think I got it.
I defined my object as function My_Object(){...} and then called it with MyObject(). This way the My_Object was treated as a function, not an object and therefore this == window.
So in the end I was attaching properties and methods to window instead of My_Object! That's way there were available without prepending .this.
The right way to initialize My_Object as an object is to call it like this new My_Object, isn't right?

what is the meaning of word this near the property in JavaScript

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

Javascript Mutable Parameter?

This is just a technical question about javascript. In javascript, one member of my group found something odd with javascript object creation. For some reason, the parameters in the object are already treated as members without assigning them to any member variables created in the constructor of the object. The parameters are mutable also as seen in the code block below.
Here's the code to show the testing we have being doing.
function NamedItem(name)
{
name = 5;
this.getName = function ()
{
return name;
}
}
document.write(namedItem.getName() + "\n"); //5
Is this legitimate? Is it dangerous?
That's called a closure.
Nested functions can access variables from their parent function and extend the variables' lifetimes beyond the execution of the parent function.
It has nothing to do with objects.
Just to be clear there are some potentially silly things about what you're doing. Let me explain a few principles.
If you declare a variable or variables as arguments to a function such as function(arg1, arg2), in terms of the variables themselves (and not their values) it is essentially the same as saying at the top of your function var arg1; var arg2;. The are declared for you automatically. Even if you try and redeclare them, they'll still work with the passed in arguments!
Functions are objects. Objects can have properties. Therefore functions can have properties, such as this.getName = function().
Like the #SLaks pointed out you're creating a closure in your version of the getName method. A closure captures the state of things above it when it's created. Therefore if there is a name variable in its scope when it's created, it will have access to that name variable in it's scope. It's a very normal practice in JavaScript and you've managed to create a private property (name) with a public accessor function (getName). Well done.
I assume you're using creating instances of NamedItem with the new keyword like this. var item = new NamedItem("javascripter"). Another way (and one that uses less memory than what you are doing is to add the getName() function to the prototype for NamedItem like I show below. The drawback to the prototype approach is that you could just as easily access _name directly. There are no private properties in the traditional sense in JavaScript, but some people use the underscore prefix to indicate to people that they're private and not to use them. This approach (prototypes) use less memory than your approach because if you create multiple instances of NamedItem they all share a single prototype.
Using the prototypes instead:
function NamedItem(name) {
this._name = name
}
NamedItem.prototype.getName = function() {
return this._name
}
Hope that gives you some things to think about!
J

Categories

Resources