var peopleFactory = function(name, age, height) {
var temp = {};
this.name = name;
this.age = age;
this.height = height;
temp.printPerson = function() {
console.log(this.name + '' + this.age + '' + this.height);
document.write(this.name + '' + this.age + '' + this.height);
};
return temp;
};
var person1 = peopleFactory('tanmay', 27, 5.11);
var person2 = peopleFactory('chinmay', 37, 5.12);
person1.printPerson();
person2.printPerson();
Not sure but here you go. Just make it a class.
class peopleFactory {
constructor(name, age, height) {
this.name = name;
this.age = age;
this.height = height;
}
printPerson() {
return this.name + ' ' + this.age + ' ' + this.height;
};
};
var person1 = new peopleFactory('tanmay', 27, 5.11);
console.log(person1.printPerson())
You should not be using this in your factory as it's a reference to the global object (unless you want to call your factory with the new keyword. But then, it wouldn't be a factory anymore).
Instead, you could be using another local object where you would store your object's private data. By doing that, your printPerson() function becomes a closure and can access data inside that local object and will be able to print it once it's invoked.
var peopleFactory = function(name, age, height) {
var temp = {}, instance = {};
temp.name = name;
temp.age = age;
temp.height = height;
instance.printPerson = function() {
console.log(temp.name + ' ' + temp.age + ' ' + temp.height);
document.write('<br/>' + temp.name + ' ' + temp.age + ' ' + temp.height);
};
return instance;
};
var person1 = peopleFactory('tanmay', 27, 5.11);
var person2 = peopleFactory('chinmay', 37, 5.12);
person1.printPerson();
person2.printPerson();
Related
I have a simple prototype chain, and I want to get the name of all prototypes that are a part of it:
function Animal(name, age){
this.name = name;
this.age = age;
this.eat = function(){console.log(name + " eats");}
this.getAge = function(){console.log(name + " is " + age + " years old");}
}
function Cat(name, age){
Animal.call(this, name, age);
this.hunt = function(){console.log(name + " hunts mice")};
}
Cat.prototype = new Animal();
var cat1 = new Cat("cat1", 2);
var currentPrototype = cat1;
while(currentPrototype != null){
console.log(currentPrototype.constructor.name);
currentPrototype = Object.getPrototypeOf(currentPrototype);
}
I would expect to get Cat, then Animal, then Object. However, I am getting:
Animal
Animal
Animal
Object
Can someone explain to me why this happens, and how to get the correct result. Is my whole prototype inheritance wrong..?
When you did Cat.prototype = new Animal();, you made
[[prototype]] of Child be a ref to Parent.
This changes the child's constructor pointing to parent.
you need to explicitly set
Cat.prototype.constructor = Cat;
See the below example:
function Animal(name, age){
this.name = name;
this.age = age;
this.eat = function(){console.log(name + " eats");}
this.getAge = function(){console.log(name + " is " + age + " years old");}
}
function Cat(name, age){
Animal.call(this, name, age);
this.hunt = function(){console.log(name + " hunts mice")};
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat1 = new Cat("cat1", 2);
var currentPrototype = cat1;
while(currentPrototype != null){
console.log(currentPrototype.constructor.name);
currentPrototype = Object.getPrototypeOf(currentPrototype);
}
In an OOP way, I am defining a Person "class" as follows:
var Person = {
name: '',
age: 32,
gender: 'male',
interests: ['music', 'skiing'],
bio: function() {
alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
},
greeting: function() {
alert('Hi! I\'m ' + this.name + '.');
}
};
Now, I am instantiating the above class.
var person1= Object.create(Person);
person1.name = 'personname';
person1.greeting();
How can I mimic a constructor so that when Object.create(Person) creates a new object, the constructor code is automatically computed?
You would wrap up the code in a function, and call it there. Object.create will establish a relationship with the prototype, but won't call any additional code automatically.
function person(name) {
var person1 = Object.create(Person);
person1.name = name;
return person1;
}
person('personname').greeting();
You should also avoid uppercasing the first letter of variables unless they are functions which should be called using new. This is a naming convention used only for constructor functions.
You could make an real class for use with new.
var Person = function () {
var Person = function () {
this.name = ['', ''];
this.age = 32;
this.gender = 'male';
this.interests = ['music', 'skiing'];
};
Person.prototype.bio = function() {
return this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.';
};
Person.prototype.greeting = function() {
return 'Hi! I\'m ' + this.name + '.';
};
return Person;
}();
var p1 = new Person;
p1.name = ['Tom', 'Sawyer'];
console.log(p1.bio());
console.log(p1);
var Person = function(name) {
this.name = name || '';
this.age = 32;
this.gender = 'male';
this.interests = ['music', 'skiing'];
this.bio = function() {
alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
};
this.greeting = function() {
alert('Hi! I\'m ' + this.name + '.');
};
};
var person1= new Person('personname');
person1.greeting();
I'm trying to call the age, name and height together, from only 1 variable called this.anh from the function called person.
The way i wrote the list is wrong but what is the right notation? if there is multiple ways, please write them down. :)
<script type="text/javascript">
function person(age, name, height){
this.age = age;
this.name = name;
this.height = height;
this.anh = age, name, height;
}
var koolz = new person(20,"koolz",200);
document.write(koolz.anh)
</script>
You need to add literals where you want them and concatenate the dynamic values.
function person(age, name, height){
this.age = age;
this.name = name;
this.height = height;
// If you want a literal comma and space to separate the values
// then you need to concatenate them to the variables.
this.anh = age + ", " + name + ", " + height;
// Or, if the data were in an array, like this:
var arry = [this.age, this.name, this.height ];
// You could concatenate them like this:
var result = arry.join(", ");
console.log(result);
}
var koolz = new person(20,"koolz",200);
document.write(koolz.anh)
You need to concatenate the variables to get your expected output.
this.anh = age + ', ' + name + ', ' + ', ' + height;
function person(age, name, height) {
this.age = age;
this.name = name;
this.height = height;
this.anh = function() {
return this.age + ", " + this.name + ", " + this.height;
};
this.anh2 = age + ", " + name + ", " + height;
}
var koolz = new person(20, "koolz", 200);
console.log(koolz.anh())
console.log(koolz.anh2)
koolz.age = 25;
koolz.height = 210;
console.log("This has the updated values.")
console.log(koolz.anh())
console.log("Other way doesn't ever change")
console.log(koolz.anh2)
Since age, name and height are public properties you should use a function for "anh" so that it always returns an up to date value. Otherwise "anh" could get out of sync with the other variables very easily.
ES5
this.anh = age + ', ' + name + ', ' + height;
ES6 (template literal)
this.anh = `${age}, ${name}, ${height}`;
And instead of creating a new variable, you can override the toString method:
function person(age, name, height) {
this.age = age;
this.name = name;
this.height = height;
}
person.prototype.toString = function () {
return this.age + ', ' + this.name + ', ' + this.height;
}
var koolz = new person(20, 'koolz', 200);
koolz.toString() // "20, koolz, 200"
I have this object:
function Boy(n,s,a)
{
this.name = n;
this.surname = s;
this.age = a;
this.getInfo = function(){
return this.name + ' ' + this.surname + ' (' + this.age + ')';
}
}
I want to do something like this:
{{ boy.getInfo() }}
and not like this:
{{ boy.name }} {{ boy.surname }} ({{boy.age}})
is it possible?
there are some tricks for doing something similar?
Absolutely! You can create an object and shove it into $scope just like anything else.
var NameController = function ($scope) {
$scope.boy = new Boy("Foo", "Bar", 32);
};
NameController.$inject = ['$scope'];
app.controller("NameController", NameController);
And then bind it in the UI just like so:
<h3>{{boy.getInfo()}}</h3>
Here is an example of binding to all three properties and seeing the result of the function: http://jsfiddle.net/jwcarroll/Pb3Cu/
You can bind $scope functions normally
function MyController($scope){
$scope.myfunc = function(){
return "test";
}
}
and then, in the view
{{ myfunc() }}
You can do something like:
function Boy(n,s,a)
{
this.name = n;
this.surname = s;
this.age = a;
this.getInfo = function(){
return this.name + ' ' + this.surname + ' (' + this.age + ')';
}
}
var boy = new Boy(n, s, a);
$scope.boy = function(){
return boy.getInfo();
}
And in you template just bind {{boy()}}.
Trying to understand prototypes. I'm playing around in Chrome's console and was hoping someone can point me to why this is happening.
function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}
Gadget.prototype.price = 100;
Gadget.prototype.rating = 3;
Gadget.prototype.getInfo = function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
};
var newtoy = new Gadget('webcam', 'black');
newtoy.constructor.prototype
Gadget {price: 100, rating: 3, getInfo: function} //Expected
Now if I try the following, prototype does not have the expected results.
function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}
Gadget.prototype = {
price: 100,
rating: 3,
getInfo: function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
}
};
var newtoy = new Gadget('webcam', 'black');
newtoy.constructor.prototype
Object {} //Empty Object!!!!!???
jsFiddle Demo
This is because you overwrote the prototype instead of extending it when you did this:
Gadget.prototype =
It is common when overwriting it, to make a facade of the constructor like this:
Gadget.prototype = {
constructor : Gadget
}
So for your exact situation:
Gadget.prototype = {
constructor : Gadget,
price: 100,
rating: 3,
getInfo: function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
}
};
Prototype is initially a special typed object. When you assign the prototype with a new object (the curly braces are short hand for a new object) you lose the special prototype object.
See How does JavaScript .prototype work? for a deeper explanation.