Javascript : difference two ways declare variable in a function - javascript

I want to create an object. And, in almost code I have read, they often use this style:
function student(_id, _name, _year){
this.id = _id;
this.name = _name;
this.year = _year;
}
But, I don't know what the difference with below code :
function student (_id, _name, _year){
var id = _id;
var name = _name;
var year = _year;
}
I have tested for example, alert properties to screen, and see no difference.
Thanks :)

When you declare variables using var they are only visible in the scope of your function/constructor. They are private so to say.
Using this, in this case, goes hand in hand with a constructor function. When you instantiate a student all the values assigned to this will be publicly accessible.
First I recommend renaming your student into Student with a capital S. This is a convention that indicates it is a constructor and you need to use the new keyword.
function Student(id, name, year){
this.id = id;
this.name = name;
this.year = year;
}
If you now instantiate the Student you can access the values...
var student = new Student(1, "Name", 2012);
console.log(student.year); // => 2012
When using var you can't...
function Student (id, name, year){
var id = id;
var name = name;
var year = year;
}
var student = new Student(1, "Name", 2012);
console.log(student.year); // => undefined

function student(_id, _name, _year){
this.id = _id;
this.name = _name;
this.year = _year;
}
var s1 = new student(1, 'mike', 20);
console.log(s1.name); // give you mike
function student(_id, _name, _year){
var id = _id;
var name = _name;
var year = _year;
}
var s1 = new student(1, 'mike', 20);
console.log(s1.name); // give you undefined

Its about the scope of the variables.
In your first example, you are assigning id, name, and year as externally accessible properties for student. For example:
student.id, student.name, student.year
However, in the second example, those variables only have scope inside the student function. You cannot access their values from the outside.

the difference is the properties are public in the first while privat in the second.
there is no difference of leading var with or without underscore. the second example missmatching the arguments. id vs _id.

Related

Writing a function that takes 2 separate constructor functions as its parameters using JavaScript

I am relearning JavaScript and I have run into an issue that I can not figure out. If someone has the answer to this and could give me an explanation as to where I have gone wrong I would greatly appreciate it.
I have 2 functions, 1 is called Person with the parameters (name, petProp). I set petProp to look at the second function which is called Pet with the parameters of (name, species).
I then create a new Person and a new Pet.
Next I create a function which will assign the pet to the person. I want to be able to add new people and new pets to this.
Lastly I want to write a reportPets function that takes a Person object as a parameter and outputs to the console the person's name followed colon followed by a comma-separated list of pets with the species of pet in parentheses after each pet.
My issue is the first 3 functions and getting them to work properly. I can get a console.log output which has 4 parameters where I am really only looking for 3. Here is the code and I do hope that these questions make sense.
function Person(name, petProp) {
this.name = name;
this.petProp = Pet;
}
let myPerson = new Person("Mary");
function Pet(name, species) {
this.name = name;
this.species = species;
}
let myPet = new Pet("Fluffy", "Cat");
function assignPetToPerson(Pet, Person) {
return this.myPet + " " + this.myPerson;
}
assignPetToPerson(myPet, myPerson);
console.log(myPerson, myPet);
Any help is greatly aprreciated to further my knowledge and understanding of this. Thank you.
You need to proofread carefully, and think of objects as unique items, not members of a class. You can add properties at any time.
You reference a nonexistent object Pet in your Person function. You pass in an argument petProp to that same function that you aren't doing anything with. You can just ignore the pet portion of things until you want to add it in the assignPetToPerson function.
Creating the functions and then creating the objects might help keep things clear.
function Person(name) {
this.name = name;
}
function Pet(name, species) {
this.name = name;
this.species = species;
}
function assignPetToPerson(Pet, Person) {
Person.pet = Pet;
}
const myPet = new Pet("Fluffy", "Cat");
const myPerson = new Person("Mary");
assignPetToPerson(myPet, myPerson);
console.log(myPerson);
I assume you want to have myPet as the petProp of myPerson?
This is (one of the many ways) how you can achieve that:
function Person(name) {
this.name = name;
this.setPet = function(pet) {
this.petProp = pet;
}
}
let myPerson = new Person("Mary");
function Pet(name, species) {
this.name = name;
this.species = species;
}
let myPet = new Pet("Fluffy", "Cat");
myPerson.setPet(myPet);
console.log('myPerson:', myPerson);
console.log('myPet:', myPet);
What the code does it to create a public method setPet for every Person instances. Instances are created by calling new Person().
The public method can be called from the instance, so you can call myPerson.setPet(myPet). The setPet function will set this.petProp according to the value of myPet.
this in this context refers to the instance itself. For example, if you are calling myPerson.setPet(), the this in setPet refers to myPerson. You can test this by accessing myPerson.petProp directly after setting the pet, the value will be the same.
BUT,
you actually don't need to create a public method for this purpose. You can just do myPerson.petProp = myPet. Javascript is very dynamic like that. But if you are coming from an OO background, this might be something you want to know that is possible in Javascript.
function Person(name, petProp) {
this.name = name;
this.petProp = Pet;
}
var myPerson = new Person("Mary");
function Pet(name, species) {
this.name = name;
this.species = species;
}
var myPet = new Pet("Fluffy", "Cat");
function assignPetToPerson() {
return this.myPerson.name + ' ' + this.myPet.name + ' ' + this.myPet.species
}
console.log(assignPetToPerson());

How do I apply methods from a constructor object to an arbitrary object [duplicate]

This question already has answers here:
Casting plain objects to class instances in javascript
(4 answers)
Closed 6 years ago.
I have a constructor object that has various fields; For a simple example, say
function Person(id, name) {
this.id = id;
this.name = name;
etc.
this.someFunction = function(xxx) {...}
}
Now, I have an arbitrary object with an id and name field
var somePerson = {id:123, name:"joe"}
I would like to inject the data from the somePerson instance into a Person constructor, so I can apply all of the methods from the Person class, but I am confused between apply, call, and bind.
I am aware that I can call a new constructor passing in all of the fields, but there are a lot of fields. Is there any easy way to just endow the somePerson instance with the methods from the Person class?
I think you got it wrong, what you are trying to do is :
var somePerson = new Person(123, 'joe');
then you will be able to write :
somePerson.someFunction();
You need to create a new Person instance, there's no need to use call or apply.
var somePerson = {id:123, name:"joe"};
var somePersonInstance = new Person(somePerson.id, somePerson.name);
somePersonInstance.someFunction(xxx);
You could have used call if the method was not inside the constructor, but on the prototype:
function Person(id, name) {
this.id = id;
this.name = name;
}
Person.prototype.someFunction = function(xxx) {…};
var somePerson = {id:123, name:"joe"};
Person.prototype.someFunction.call(somePerson, xxx);
You could use Object.assign() and assign properties of somePerson object to instance of Person
function Person(id, name) {
this.id = id;
this.name = name;
this.someFunction = function() {
return this.name;
}
}
var somePerson = {id:123, name:"joe"}
var p = Object.assign(new Person, somePerson)
console.log(p.someFunction())
Person is set up like a constructor function. You need to use the new keyword to instantiate a new copy of Person.
var joe = new Person(somePerson.id, somePerson.name);
Now joe will be an instance of Person.
joe instanceof Person //true
joe.id //123
joe.someFunction //function (xxx) {...}
Sure How's this;
function PersonFactory(id, name) {
return {
id: id,
name: name,
updateName: function(name) {
this.name = name
}
}
}
Some exmaples of it being used.
var somePerson = PersonFactory(1, "Luke")
var people = {
luke: PersonFactory(1, "Luke"),
will: PersonFactory(2, "Will"),
smith: PersonFactory(3, "Smith")
}
var persons = [
PersonFactory(1, "Luke"),
PersonFactory(1, "Will"),
PersonFactory(1, "Smith")
]
people.luke.updateName("Harry");

New Object Creation issues

Ok so the following function acts as a constructor to create an Employee object(no problem with that). But when I use this function to create 3 new employees I am messing up somewhere.
I know I'm supposed to set the properties and print the employee's name and phone number, but I am missing something or something is in the wrong place.
Thanks in advance for your help.
function Employe() {
var = name;
var = phone;
this.getName = function () {
return this.name;
}
this.setName = function (name, phone) {
this.name = name;
this.phone = phone;
};
}
var emp1 = newEmployee;
this.Name = 'jo';
this.Phone = ' 555-5551'
document.write(Employee.name Employee.phone);
var emp2 = newEmployee;
this.Name = 'jim';
this.Phone = '555-5552';
document.write(Employee.name Employee.phone);
var emp3 = newEmployee;
this.Name = 'jon';
this.Phone = '555-5553';
document.write(Employee.name Employee.phone);
In the following:
> var emp1 = newEmployee;
The variable on the left will be assigned the result of evaluating the expression on the right. There is no identifier newEmployee, so you will get an error. What you probably meant to write is:
var emp1 = new Employee();
That will call the constructor, which will return a new instance, a reference to which will be assigned to emp1.
Then you have:
> this.Name = 'jo';
The value of this is set when entering an execution context. For global code, it always references the global object (which is equivalent to window in a browser). So the above line creates a Name property of the global object and assigns the value 'jo';
What you wanted is probably:
emp1.setName('jo','555-5551');
The name of that method seems inappropriate given that it sets both the name and phone number.
> document.write(Employee.name Employee.phone);
Since you added the properties to the instance (emp1), likely that's the properties you want to read:
document.write(emp1.name + ' ' + emp1.phone);
or to use the getName method:
document.write(emp1.getName() + ' ' + emp1.phone);
and so on.
There's a lot wrong with your code example. The constructor is misspelled. The employee instances should be created like:
var emp1 = new Employee();
The instance properties should be set like:
emp1.setName('John');
You've also combined two setters into one, which is confusing.
To access the instance properties, you should use:
emp1.getName();
Not:
Employee.Name
Yes you have a lot of errors I think this is basically what you want to achieve.
function Employee(){
this.name;
this.phone;
this.getName = function(){
return this.name;
};
this.setName = function(name, phone){
this.name = name;
this.phone = phone;
};
}
function employ(){
var emp1 = new Employee();
emp1.name = 'jo';
emp1.phone = ' 555-5551' ;
alert(emp1.getName());
}
http://jsfiddle.net/umNTs/

Define a "nested" object constructor in JavaScript?

Is it possible to define an object within another object? I'm thinking something like this:
function MyObj(name) {
this.name = name;
function EmbeddedObj(id) {
this.id = id;
}
}
And I could then create an EmbeddedObj like this:
var myEmbeddedObj = new MyObj.EmbeddedObj();
Meme for bonus points: Objectception! :o
Yes, and no.
function MyObj(name) {
this.name = name;
}
MyObj.EmbeddedObj = function EmbeddedObj(id) {
this.id = id;
}
new MyObj.EmbeddedObj(42);
Would run, but it might not yield the expected results for "embedded object" (see comment).
Note that in the case of new expr the expression is evaluated first so, in this case it creates a new object using the function-object evaluated from MyObject.EmbeddedObj as a constructor. (There is a silly rule with parenthesis in the expression, but that's another story.)
Now, if a "parent" and "child" relationship was desired, that could be done, using a more round-about method:
function Parent (name) {
this.name = name;
var parent = this; // for closure
this.Child = function Child () {
this.Parent = parent;
}
}
// create new parent object
var parent = new Parent();
// each new parent has a different Child constructor and
// any function-object can be used as a constructor
var child = new parent.Child();
// true: child is "bound" to parent
child.Parent === parent;
function MyObj(name) {
this.name = name;
}
MyObj.EmbeddedObj = function(id) {
this.id = id;
}
var myEmbeddedObj = new MyObj.EmbeddedObj();
Does that look like what you're after?
Here is example of nested constructor.
function cimdb(name,review,year) {
function nestedConstructor(name,review,year) {
this.name = name;
this.review = review;
this.year = year
};
this.name = name;
this[name] = new nestedConstructor(name,review,year);
}
var lionking = new cimdb("The Lion King", "The lion King review ..", 2015);
I guess this is what you mean by nested object constructor.
The easiest way to nest other objects in a constructor is to create its field and then create a new object when invoking the constructor. Below is an example:
function Product(name, price, category, producer) {
this.name = name;
this.price = price;
this.category = category;
// nested constructor
this.producer = producer;
}
function Producer(contributor, address) {
this.contributor = contributor;
this.address = address;
}
let prod1 = new Product("Milk", 2.5, "Dairy", new Producer("Nestle", "Warszawa"));

how to access javascript object variables in prototype function

I have the following javascript
function person() {
//private Variable
var fName = null;
var lName = null;
// assign value to private variable
fName = "Dave";
lName = "Smith";
};
person.prototype.fullName = function () {
return this.fName + " " + this.lName;
};
var myPerson = new person();
alert(myPerson.fullName());
I am trying to get an understanding of object orientated techniques in javascript. I have a simple person object and added a function to its prototype.
I was expecting the alert to have "Dave Smith", however I got "underfined underfined". why is that and how do I fix it?
Unfortunately you can't access a private variable. So either you change it to a public property or you add getter/setter methods.
function person() {
//private Variable
var fName = null;
var lName = null;
// assign value to private variable
fName = "Dave";
lName = "Smith";
this.setFName = function(value){ fName = value; };
this.getFName = function(){ return fName; }
};
see javascript - accessing private member variables from prototype-defined functions
But actually this looks like what you are looking for:
Javascript private member on prototype
from that SO post:
As JavaScript is lexically scoped, you can simulate this on a per-object level by using the constructor function as a closure over your 'private members' and defining your methods in the constructor, but this won't work for methods defined in the constructor's prototype property.
in your case:
var Person = (function() {
var store = {}, guid = 0;
function Person () {
this.__guid = ++guid;
store[guid] = {
fName: "Dave",
lName: "Smith"
};
}
Person.prototype.fullName = function() {
var privates = store[this.__guid];
return privates.fName + " " + privates.lName;
};
Person.prototype.destroy = function() {
delete store[this.__guid];
};
return Person;
})();
var myPerson = new Person();
alert(myPerson.fullName());
// in the end, destroy the instance to avoid a memory leak
myPerson.destroy();
Check out the live demo at http://jsfiddle.net/roberkules/xurHU/
When you call person as a constructor, a new object is created as if by new Object() and assigned to its this keyword. It is that object that will be returned by default from the constructor.
So if you want your instance to have properties, you need to add them to that object:
function Person() {
// assign to public properties
this.fName = "Dave";
this.lName = "Smith";
};
Incidentally, by convention functions that are intended to be called as constructors are given a name starting with a capital letter.
You're declaring those variables as local to the function, instead of making them part of the object. In order to put them in the instance, you've got to use 'this' in the constructor as well. For example:
function person() {
this.fName = 'Dave';
this.lName = 'Smith';
}
person.prototype.fullName = function () {
return this.fName + " " + this.lName;
};
var myPerson = new person();
alert(myPerson.fullName());
In the constructor you should assign your variables to this:
this.fName = null;
this.lName = null;
But then they are not private. JavaScript does not have private variables like a "classic" Object Oriented language. The only "private" variables are local variables. An alternative to the above is to assign getter/setter methods to this within the constructor.

Categories