JavaScript constructor parameter or this.property - javascript

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?.

Related

Using "call" properly in Javascript to access object properties

I'm new to Javascript, and despite having read several threads and tutorials online, I can't correctly use "call" in this example to access the property of the object
I know the problem is that when "b ()" is called, "this" is the global object, and I have to use the call (or apply) method to make sure that when "b" is called this is set to the object itself, but I can't find the error.
I know that arrow functions exist, and that there may be other approaches, but I want to understand what is the matter with this using of call. Thank you.
The code is
class Letter {
constructor() {let a = "a";}
b() {alert (this.a);} //can't access a. Prints "undefined"
c() {this.b.call(this);}
}
let p = new Letter ();
p.c();
The a does not exist as a property of the object - it's a variable, an identifier visible within the constructor function, not an instance on an object.
There's no good way to gain access to a variable declared in another scope like that. For what you're trying to accomplish, define a as a property of the instance instead.
constructor() {
this.a = 'a';
}
You won't need .call at all - just do this.b().

Names of Objects properties vs Constructor function arguments in 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.

referring to prototype method within class variable

I'm having trouble with a JS prototype object I'm working on. What I'm trying to do is define a class-level variable as an object literal, then refer back to one of the class's prototype methods to set a property of the class-level variable, but I'm not getting anywhere. Here's what I am trying to do, in a simplified example:
var foo = function(args)
{
this.name = 'bar';
}
foo.stuff = { barbaz: this.foobarbaz(2) };
foo.prototype.foobarbaz(int)
{
return int;
}
alert(foo.stuff.barbaz); // should alert 2, but I'm missing something
I'm wondering if I'm just misunderstanding the scope of 'this' in this instance, or if this.foobarbaz() is undefined when I assign it to foo.stuff.barbaz.
Is it possible to refer to an object's prototype methods from within a class-level variable like this?
Here is what you need to know:
You should define your method on the prototype like foo.prototype.foobarbaz = function(int) {...}. Your current syntax is not valid.
You're trying to use the method before you define it. If you're expecting function hoisting to work here, that only applies to function declarations, not assignments. Move the assignment of foobarbaz above the first time you use it.
In this function you've provided, this is not foo. Each function has its own value of this (called the function's "context"), set each time the function is invoked. You can see the rules for how a function's context is set in several answers to Understanding Javascript scope with "var that = this".
Instead, here, you'll need to use foo.foobarbaz(2) instead of this.foobarbaz(2), because this is probably window (assuming you call this code not as the method of an object and not in JavaScript's strict mode).

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?

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