javascript constructor function not giving correct result - javascript

i am a newbie to js.
i am trying to use constructor function to create an object.
here is my code
function player(name,age,rank)
{
this.name=name;
this.age=age;
this.rank=rank;
this.sayEverything=function()
{
return "The name of the player is " + this.name + "the age is " + this.age + "the rank is " + this.rank;
}
Now i am adding a new property like this
player.matchReady=true;
now i create an object like this
var kaka=new player("kaka",22,3,false);
And when i write this
document.write('kaka is match ready-->' + kaka.matchReady);
it gives me this output
kaka is match ready-->undefined
Why is it giving me undefined??
haven't i added a new property correctly??Please tell me.
Thanks.

Instead of player.matchReady=true;
Do, player.prototype.matchReady = true;
This way all players will have match ready default on true;
also you might want to put your function into the prototype.
player.prototype.sayEverything=function()
{
return "The name of the player is " + this.name + "the age is " + this.age + "the rank is " + this.rank;
}
You can regard prototype as the scaffolding on which you outline all properties and functions an object should have when it's instantiated. All these default values will be the same for all objects.
When you add functions within functions all these functions get duplicated in memory when you instantiate a new object.
When possible and when there is no need for scoping, try to add generic functions like your sayEverything()(please rename that to toString() to keep in line with convention) to the prototype.
That way all the player objects can use the same function. Which is more memory efficient.

You cannot add a property to a class. You can always add the property as its prototype.
like this:
function player(name, age, rank) {
this.name = name;
this.age = age;
this.rank = rank;
this.sayEverything = function () {
return "The name of the player is " + this.name + "the age is " + this.age + "the rank is " + this.rank;
}
}
player.prototype.matchReady = true;
var kaka = new player("kaka", 22, 3, false);
alert('kaka is match ready-->' + kaka.matchReady);
working example: jsfiddle
Blog on prototype

If you add it to the prototype, all player will have the field.
player.prototype.matchReady = true;
If you only want a specific player to have the field, add it to that player variable:
var kaka = new player("kaka",22,3,false);
kaka.matchReady = true;// kaka has to come first

In the below example you can see what is private ,public,static and privileged variable or method .When ever you write property on Method itself like static variable,that variable wont be available for the instances.
Also whenever you are writing constructor function you should follow the Naming convention to help you differentiate from other function
/ Constructor
function Player(name) {
// Private
var dob= "17/04/1986";
// Privileged
this.getDOB = function () {
return dob;
};
// Public
this.name = name;
}
// Public
Player.prototype.getName = function () {
return this.name;
};
// Static property
Player.town = "South Park";

Related

Extending objects functionalities in JavaScript through prototypes

I'm studying JavaScript autodidactically, I was searching for ways to inherit from objects and extend their functionalities as well...and... wow! it turns out there are several ways to do it.
So there is a popular one which is extending an object through extend and class keywords (to say it in short) of which I put an example of what I saw right underneath. Ok, since I come from C++ and Python languages, this is indeed! very helpful... but I'm aware of this is sugar code to help programmers who come from object-oriented languages feel JavaScript cozier. So!, my goal is to know how to extend objects functionalities without using the aforementioned method since I'm eager to understanding how js works under the hood (at least to nighing considerably to it) and feeling comfortable with it.
Note
I know there are posts here on this topic, but i think those don't meet my needs, considering those which (are very good) dig deep into it are from around 2012.
With class and extend keywords way
REFERENCE: https://www.geeksforgeeks.org/how-to-extend-an-object-in-javascript/
// Declaring class
class Profile {
// Constructor of profile class
constructor(name, age) {
this.name = name;
this.age = age;
}
getName() {
// Method to return name
return this.name;
}
getAge() {
// Method to return age
return this.age;
}
getClass() {
return this;
}
}
// Class Student extends class Profile
class Student extends Profile {
// Each data of class Profile can be
// accessed from student class.
constructor(name, age, languages) {
// Acquiring of attributes of parent class
super(name, age);
this.lang = [...languages];
}
// Method to display all attributes
getDetails() {
console.log("Name : " + this.name);
console.log("Age : " + this.age);
console.log("Languages : " + this.lang);
}
}
// Creating object of child class with passing of values
var student1 = new Student("Ankit Dholakia", 24,
['Java', 'Python', 'PHP', 'JavaScript']);
student1.getDetails();
I tried this... but I'm not comfortable!
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.selfPresentation = function() {
console.log("Hello, my name is " + this.name + "and I'm " + this.age + " years old.");
}
function Worker(name, age, occupation) {
Person.call(this, name, age);
this.occupation = occupation;
}
Worker.prototype = new Person;
Worker.prototype.selfPresentation = function() {
// I think there undoubtedly is a best approach for this...
this.__proto__.__proto__.selfPresentation.call(this);
console.log("I don't breath only, I'm a " + this.occupation);
}
let variable = new Worker("Arturo", 22, "Student");
variable.selfPresentation();
(This is a little aside my goal but..) For inheritance between objects I tried to mimic Object.create method
a = {
field: "field",
method: function() {
console.log("SuperMethod");
}
}
function inheritHimAll(object) {
function helperFunction() {}
helperFunction.prototype = object;
return new helperFunction;
}
b = inheritHimAll(a);
console.log(b.__proto__)
What would be the best approach for extending objects in javascript?
What would be the best approach for extending objects in javascript?
This is quite a subjective question, but I use the class syntax when I can. They are more intuitive, and require less boilerplate code.
However, I think you are more interested in knowing how to do inheritance without the class syntax. Here's what I would change from your example:
Don't create a new instance of the class for prototype. The properties all live in the object, not in the prototype. Instead, use Object.create() to create a new object with the class's prototype. See this answer for more information about this.
Never use __proto__. Instead, call the function from the class's prototype manually or use Object.getPrototypeOf().
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.selfPresentation = function() {
console.log("Hello, my name is " + this.name + "and I'm " + this.age + " years old.");
}
function Worker(name, age, occupation) {
Person.call(this, name, age);
this.occupation = occupation;
}
Worker.prototype = Object.create(Person.prototype);
Worker.prototype.selfPresentation = function() {
Person.prototype.selfPresentation.call(this);
console.log("I don't breath only, I'm a " + this.occupation);
}
let variable = new Worker("Arturo", 22, "Student");
variable.selfPresentation();

Define getter / setter in object function

I'm learning JavaScript, and was wondering if it was possible to define getters and setters in object functions.
The main difference is the way of calling it, if defined as getFullName = function(), I should call the method as myObj.getFullName(), however, as for arrays, a getter allows for it to be called as a simple property myObj.fullName (without parenthesis).
As I saw in MDN reference (http://mzl.la/1CIUuIw), it is easily done in Object Literals:
var obj = {
get var(){
return "something";
}
}
However, I can't do it on object functions like so:
function obj(name, lname){
this.name = name;
this.lastName = lname;
get fullName(){
return this.name + " " + this.lastName;
}
}
Getting a "Unexpected identifier" error...
As get XX(){} is used for var obj = {}; But here you use a constructor to create new object. So you should use MDN - Object.defineProperty().
And if you want the fullName apply on all object create from obj, apply it on its prototype.
function obj(name, lname){
this.name = name;
this.lastName = lname;
}
Object.defineProperty(obj.prototype, 'fullName', {
get : function() {
return this.name + " " + this.lastName;
}
});
var aObj = new obj("first", 'lastN');
console.log(aObj.fullName);
UPDATE:
If you want a more straight way, and not scared to try new things, then ES2015's class notation can do it more easily:
// ES2015 - class
class obj {
constructor(name, lname) {
this.name = name;
this.lname = lname;
}
// Define getter method for fullName
get fullName() {
return this.name + " " + this.lastName;
}
}
var aObj = new obj('Billy', 'Hallow');
console.log(aObj.fullName);
Currently most browsers don't support that, if you want to use this in your site, you need to use js compilers like Babel to transpile it from ES2015 to ES5.
Babel also provide a playground for those who has interest in ES2015, you can copy above codes to the playground to see how it works.
Javascript uses prototype inheritance and its functions start with function keyword. By convention, object's first character is capitalised.
function Obj(name, lname){
this.name = name;
this.lastName = lname;
}
Obj.prototype.get = function() {
return this.name + " " + this.lastName;
}
var person = new Obj('luke', 'lim');
console.log(person.get()); // 'luke lim'
Just make a variable and assign the function to it.
function obj(name, lname){
this.name = name;
this.lastName = lname;
this.fullName = function(){
return this.name + " " + this.lastName;
};
}
Try to read something about Javascript closure if you want to know more about it.
Furthermore, this link, Javascript methods, is explaining EXACTLY what you need, which is adding a method to an object. And a getter is traditionally just a method.
function obj(name, lname){
this.name = name;
this.lastName = lname;
}
obj.prototype.getfullName = function(){
return this.name + " " + this.lastName;
}
use this as
a = new obj("My","Name");
a.getfullName() //"My Name"

Get the public properties of a class without creating an instance of it?

Let's imagine that we have a JavaScript class:
var Person = (function () {
function Person(name, surname) {
this.name = name;
this.surname = surname;
}
Person.prototype.saySomething = function (something) {
return this.name + " " + this.surname + " says: " + something;
};
return Person;
})();
I want to iterate its methods and properties. I have no problem with the methods.
var proto = Person.prototype,
methods = Object.keys(proto);
// iterate class methods ["saySomething"]
for (var i = 0; i < methods.length; i++) {
// do something...
}
My problem comes when I want to iterate its properties:
var proto = Person.prototype,
targetInstance = new Person(), // this is my problem!
properties = Object.getOwnPropertyNames(targetInstance),
// iterate class properties ["name", "surname"]
for (var i = 0; i < properties.length; i++) {
// do something...
}
The only way that I have found is to create an instance and use Object.getOwnPropertyNames. I want to use this code as part of a framework so I will not have control over the classes defined by other developers. I want to avoid the need of creating an instance because if the constructor had some sort of validation like:
function Person(name, surname) {
if(typeof name === "undefined" || typeof surname === "undefined"){
throw new Error()
}
this.name = name;
this.surname = surname;
}
I wouldn't be able to use the code above. Do you know if it is possible to get the public properties of a class without creating an instance of it?
The properties don't exist until an object constructs them.
If your class looked like:
var Person = (function () {
Person.prototype.name = null;
Person.prototype.surname = null;
function Person(name, surname) {
this.name = name;
this.surname = surname;
}
Person.prototype.saySomething = function (something) {
return this.name + " " + this.surname + " says: " + something;
};
return Person;
})();
you would see name and surname too, but of course you can't count on the objects looking like that.
Do you know if it is possible to get the public properties of a class without creating an instance of it?
If you are talking about runtime them no, not without ugly hacks like toString (which gives you a string representation of the function body).
However you can get these at compile time using the TypeScript language service and then do code generation to assist the runtime (https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API).
Neither of these are trivial.

What am I doing wrong when combining objects with the module pattern

This Possible duplicate did not help me, I failed on an interview because of a similar question.
The idea is to create a person Object that is a father of teacher and grandfather of Manager using module pattern and inheritance.
Something like that Manager->Teacher->Person
My code looks like that(My Plunk):
(function(undef)
{
/**Waiting till document is ready before applying next functions*/
$(document).ready(function(){
var person = new APP.Person('Aria Stark','223232');
document.write(person.getDetails());
})();
var APP = {};
APP.Person =(function() {
function Person(name, ID) {
this.name = name;
this.ID = ID;
}
Person.prototype.getDetails = function() {
return " name: " + this.name + " ID: " + this.ID;
};
return Person;
});
APP.Teacher =(function () {
function Teacher(name, ID, salary, hatColor) {
APP.Person.call(this, name, ID);
this.salary = salary;
this.hatColor = hatColor;
}
Teacher.prototype = new APP.Person();
Teacher.prototype.getDetails = function() {
return APP.Person.call(this) + " Salary: " + this.salary + " Hat: " + this.hatColor;
};
return Teacher;
});
APP.Manager =(function () {
function Manager(name, ID, salary, hatColor, car) {
APP.Teacher.call(this, name, ID, salary, hatColor);
this.car = car;
}
Manager.prototype = new APP.Teacher();
Manager.prototype.getDetails = function() {
return APP.Teacher.call(this) + " Car: " + this.car;
};
return Manager;
});
})();
I get an error on the first line:
var person = new APP.Person('Aria Stark','22323');
The error is: Uncaught TypeError: object is not a function
Can someone help me with with that? I'm also open to hear other improvements to this code.
This is how you create (and call) a self-executing function or IIFE:
(function () {})();
Simply writing (function () {}) does not call the function, it actually has no real effect in this case. With your way APP.Person will be a function, that returns another function (the constructor for Person) when called - it will not operate well with new.
Also, for the documentready, you don't want to execute the result of the .ready call, just pass the function as a parameter, it will be called when the event triggers:
$(document).ready(function(){
}); //removed () from here
Plunk with these changes
All your objects are declared like this:
APP.X=(function() {
function Y() {}
Y.prototype.method= function() {};
return Y;
});
That is not wrong in itself, though it is a bit odd. What you want to have is this:
APP.X=(function() {
function X() {}
X.prototype.method= function() {};
return X;
})(); // actually call the anonymous function you used to encapsulate variables
Then again, why do you bother with an IIFE? You might just as well do this:
APP.X = function () {}
X.prototype.method= function() {};
Encapsulating them brings absolutely nothing, there is nothing private you are hiding from the outer scope.
Also, my post might be better suited for CodeReview than StackOverflow, but your inheritance model has significant issues. Your Teacher.prototype is an instance of Person created with no parameters. Only under highly restrictive circumstances will that be safe.
A better model would be this one:
Teacher = function(){
Person.call(this /*, person parameters*/);
}
Teacher.prototype = Object.create(Person.prototype);
There are many good answers on SO dealing with this specific issue, here is one from me.
There is no need of jQuery to create these things. Well, I have not very good exposer on this, but I tried to show the things you want to know:
// Creating Person Class
var Person = function(name, id){
this.name = name;
this.id = id;
};
Person.prototype.getInfo = function(){
return "name: " + this.name + ", id: " + this.id;
};
// Instance of Person
var x = new Person("Ashish", 1);
x.getInfo();
// Creating Teacher Class
var Teacher = function(name, id, salary, hatColor){
Person.call(this, name, id);
this.salary = salary;
this.hatColor = hatColor;
};
// Inheriting Persons methods
Teacher.prototype = new Person();
// Adding new method to it
Teacher.prototype.getFullDetails = function(){
return this.getInfo() + ", salary: " + this.salary + ", Hatcolor: " + this.hatColor;
}
// Instance of Teacher Class
var teacher = new Teacher("John", 2, 15000, "red");
teacher.getInfo(); //output: "name: John, id: 2"
teacher.getFullDetails(); // output : "name: John, id: 2, salary: 15000, Hatcolor: red"
console.log(teacher.salary); // output : 15000
So, above you can see:
- A Person class is created with 2 properties and one method.
- and then we created a Teacher class and inherited the method from Person class in it.
- and then added another method called getFullDetails() in it which accesses the method coming from Person class.
And this is what you are doing in the DOM.ready:
alert(x.getInfo()); // in my example:
In your example:
var APP = {};
APP.Person = function Person(name, ID) {
this.name = name;
this.ID = ID;
}
APP.Person.prototype.getDetails = function () {
return " name: " + this.name + " ID: " + this.ID;
};
var person = new APP.Person('Aria Stark', '223232');
alert(person.getDetails());

a prototype question in javascript

<script type="text/javascript">
var Person =
{
Create: function(name, age) {
this.name = name;
this.age = age;
},
showMe: function() {
return " Person Name: " + this.name + " Age: " + this.age + " ";
}
};
function New(aClass, aParams) {
function new_() {
aClass.Create.apply(this, aParams);
};
new_.prototype = aClass;
var obj = new new_();
return obj;
}
</script>
I don't quite understand the code above. Could someone tell me the meanings of Person, Create, showMe, New and new_? Thanks a lot.
Person is an object with two functions - Create and showMe. In JavaScript, there are no classes, only objects, and this is how you write up an object - using 'Object Literal Notation' (the curly braces and functions/properties separated by commas).
New is a clever re-implementation of the new keyword. Instead of classes, javascript has prototypes, and instead of creating an instance of a class you create a copy of the prototype. In this case, if you passed Person to New(), it would used as the prototype in new_.prototype = aClass, and the rest of this function will return an object with the Person prototype, which means any changes to Person later on will be inherited into obj as well (unless obj has overridden them).
`Person` -- a variable w/ 'parts' (used loosely) `Person.Create` and `Person.showMe'
`Person.Create` -- function of `Person` that sets `Person.name` and `Person.age` to its arguments
`Person.showMe` -- returns a string explaining values of `Person.name` and `Person.age`
`New` -- a function intended to instantiate new Person's thru prototypal (this is NOT class based) inheritenced
`New._new` -- `New` uses this to get it done
Basically thru prototype inheritence, even though Person is only 'made' once, other 'versions' of it can be constructed in kind. It can be used like this (try it here: http://jsfiddle.net/PBhCs/)
var Person = {
Create: function(name, age)
{
this.name = name;
this.age = age
},
showMe: function()
{
return " Person Name: " + this.name + " Age: " + this.age + " ";
}
};
function New(aClass, aParams)
{
function new_()
{
aClass.Create.apply(this, aParams);
};
new_.prototype = aClass;
var obj = new new_();
return obj;
}
var a = New(Person, ['moo', 5]);
var b = New(Person, ['arf', 10]);
alert(a.showMe() + b.showMe());

Categories

Resources