Function coming back undefined in Javascript - javascript

function people (name, age) {
this.name = name;
this.age = age;
}
var rob = new people("robert jr", 41);
var sam = new people("sam davies", 25);
function isOlderThan(age) {
if(rob.age > sam.age)
return true;
else return false;
}
I tried running it with this sam.isOlderThan(rob);
But it's not working. I'm kinda new to this, any help?

// If you want to be able to call this as sam.isOlderThan()
// you need to use a prototype to add that function to the persons
// so they all have that function bound to them.
function person (name, age) {
this.name = name;
this.age = age;
}
person.prototype.isOlderThan = function( other_person ) {
return this.age > other_person.age;
};
var rob = new person("robert jr", 41);
var sam = new person("sam davies", 25);
console.log( sam.isOlderThan( rob ) );
console.log( rob.isOlderThan( sam ) );

Hi and welcome to StackOverflow.
Assuming you mean to use the people function to define a type of class, and isOlderThan as a type of function of that class - notice the changes.
Constuctor functions (such as People) are commonly written with a leading Capital letter
For linking isOlderThan to an existing class - you should use the prototype syntax as shown below.
Inside the isOlderThan function we make a reference to this - which indicates the current object for which the isOlderThan than function was called.
Now we can call the isOlderThan function for each People object we create.
function People(name, age)
{
this.name = name;
this.age = age;
}
var rob = new People("robert jr", 41);
var sam = new People("sam davies", 25);
People.prototype.isOlderThan = function(age) {
if (this.age > age)
return true;
else return false;
}
console.log(sam.isOlderThan(50))
console.log(rob.isOlderThan(sam.age))
enter code here

The function isOlderThan is not defined on people.
You could use a prototype on people if you want to call it like sam.isOlderThan(rob);
function People(name, age) {
this.name = name;
this.age = age;
}
var rob = new People("robert jr", 41);
var sam = new People("sam davies", 25);
People.prototype.isOlderThan = function(p) {
return this.age > p.age;
};
console.log(sam.isOlderThan(rob));
console.log(rob.isOlderThan(sam));

You cannot use sam.isOlderThan because there is no isOlderThan function defined in people function ( correlate with class of other languages ).
isOlderThan is defined in global scope.
So, you can run it as isOlderThan() or window.isOlderThan() ( provided you are inside browser )
There's no need to pass age, rob or sam as they are defined in global scope and is available inside isOlderThan function.

See if this Fiddle helps:
function Person(name, age) {
this.name = name;
this.age = age;
}
var rob = new Person("robert jr", 41);
var sam = new Person("sam davies", 25);
function isOlderThan(rob, sam) {
if (rob.age > sam.age) {
return true;
} else {
return false;
}
}
console.log(`Rob is older than Sam: ${isOlderThan(rob, sam)}`);
https://jsfiddle.net/ao2ucrmq/1/

Related

the incrementAge function is returning undefined/NaN when invoked after defining the new User

sorry, the incrementAge function is returning undefined/NaN when invoked after defining the new User. I am not sure what's wrong
function User(name,age){
this.name = name;
this.age = age;
}
User.prototype.incrementAge = ()=>{
return this.age++;
}
const mike = new User("Mike",20);
console.log(mike.incrementAge());
The correct way to do this is to create a User class and create a method to raise the value of the variable age.
As you can see by calling the increment age method several times the value is added.
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
incrementAge() {
return ++this.age;
}
}
const mike = new User("Mike", 20);
console.log(mike.incrementAge());
console.log(mike.incrementAge());
The solution (by #ChrisG in comments)
function User(name, age) {
this.name = name;
this.age = age;
}
User.prototype.incrementAge = function () {
return ++this.age;
}
const mike = new User("Mike", 20);
console.log(mike.incrementAge());

indefinite call to "set function()" in JavaScript ES6 class

I am running this simple class in JavaScript but in console it give me a "Maximum call stack size exceeded" error. and help?!?
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
get name() {
return String(this.name);
}
get age() {
return String(this.age);
}
set name(name) {
this.name = name;
}
set age(age) {
this.age = age;
}
}
let p1 = new Person('Ehsan', 23);
this is a screen shot of the console
}
If you want to indicate that the age property should not be directly used, you should use a different property name than the name used by setters and getters. If the property that the setter / getter sets or gets is the same name as the setter or getter, it'll just keep calling itself, resulting in your error.
A common convention is to put an underscore before the property:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
get name() {
return String(this._name);
}
get age() {
return String(this._age);
}
set name(name) {
this._name = name;
}
set age(age) {
this._age = age;
}
}
let p1 = new Person('Ehsan', 23);
console.log(p1.age);
p1.age = 32;
console.log(p1.age);
But the property is still viewable by consumers via p1._age - if you wanted to prevent that, you can make it more private with a closure and WeakMap:
const Person = (() => {
const privateVals = new WeakMap();
return class Person {
constructor(name, age) {
const privateObj = {};
privateObj.name = name;
privateObj.age = age;
privateVals.set(this, privateObj);
}
get name() {
return String(privateVals.get(this).name);
}
get age() {
return String(privateVals.get(this).age);
}
set name(name) {
privateVals.get(this).name = name;
}
set age(age) {
privateVals.get(this).age = age;
}
}
})();
let p1 = new Person('Ehsan', 23);
console.log(p1.age);
p1.age = 32;
console.log(p1.age);
You can't have a getter / setter pair and a field with the same name. this.name = inside the setter will itself call the setter. If you really need a getter / setter, use another field, e.g. this._name = ... But to be honest: Don't use a getter / setter here. If you do person.name = 15 you should rather fix that than trying to do that with getters / setters.
I believe you just have to rename your class variables in your constructor and then you should be good to go?
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
get name() {
return String(this._name);
}
get age() {
return String(this._age);
}
set name(name) {
this._name = name;
}
set age(age) {
this._age = age;
}
}

Nested classes in AdWords Script (JavaScript) - access parent properties [duplicate]

How do you access the this object from another object instance?
var containerObj = {
Person: function(name){
this.name = name;
}
}
containerObj.Person.prototype.Bag = function(color){
this.color = color;
}
containerObj.Person.prototype.Bag.getOwnerName(){
return name; //I would like to access the name property of this instance of Person
}
var me = new Person("Asif");
var myBag = new me.Bag("black");
myBag.getOwnerName()// Want the method to return Asif
Don't put the constructor on the prototype of another class. Use a factory pattern:
function Person(name) {
this.name = name;
}
Person.prototype.makeBag = function(color) {
return new Bag(color, this);
};
function Bag(color, owner) {
this.color = color;
this.owner = owner;
}
Bag.prototype.getOwnerName = function() {
return this.owner.name;
};
var me = new Person("Asif");
var myBag = me.makeBag("black");
myBag.getOwnerName() // "Asif"
Related patterns to deal with this problem: Prototype for private sub-methods, Javascript - Is it a bad idea to use function constructors within closures?

javascript prototyping, what am i doing wrong here

http://jsfiddle.net/johnm01/c5k0yevm/
im trying to understand prototyping again but not sure what im doing wrong here, why is undefined output when the method screamName is called?
function Person1(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = function sayMyName() {
alert(this.name + this.age + this.sex);
}
};
var p1 = new Person1("tim", 56, "male");
p1.sayName();
Person1.prototype.screamName = function screamName(name) {
this.name = name;
alert(this.name);
};
p1.screamName();
The screamName function expects a name argument which you're not supplying, and subsequently are assigning to this.name. Thus, it is undefined. I believe you intended to write this:
Person1.prototype.screamName = function screamName() {
alert(this.name);
};
Well, it looks like you've defined your method to take in a parameter of "name", but you haven't actually passed any parameter into the method when you call it. I also think that you need to create a new Person1 object in order to have a Person1 object with the screamname method.
function Person1(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = function sayMyName() {
alert(this.name + this.age + this.sex);
}
}
var p1 = new Person1("tim", 56, "male");
p1.sayName();
Person1.prototype.screamName = function screamName() {
alert(this.name);
};
var p2 = new Person1("bob", 22, "male");
p2.screamName();
https://jsfiddle.net/johnm01/c5k0yevm/

javascript private variable through inheritance

I'm stuck with a problem using javascript...
I want to declare a private variable in a class that can't be used from its sublclass...what I've tried is:
function Person(){
var _name
this.setName = function(name){
_name = name
}
this.getName = function(){
return _name
}
}
function GreetingPerson(){
var self = this;
self.sayHello = function(){
console.log(self.getName() + ': "Hello!"');
}
}
GreetingPerson.prototype = new Person()
GreetingPerson.prototype.contructor = GreetingPerson;
var manuel = new GreetingPerson()
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson()
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel.name)
In this way the name variable is private, but it is also static, so the last wo sayHello method calls, will write the same output.
I've tried also changing the Person class in this way:
function Person(){
this.setName = function(name){
this.name = name
}
this.getName = function(){
return this.name
}
}
But in this way it is not longer private.
What is the correct way to achieve it?
EDIT: Using something like #teddybeard says, you can get it too:
function Person(){
var _name;
this.setName = function(name){
_name = name;
};
this.getName = function(){
return _name;
};
return this;
}
function GreetingPerson(){
Person.call(this);
this.sayHello = function(){
console.log(this.getName() + ': "Hello!"');
};
return this;
}
GreetingPerson.prototype = new Person();
GreetingPerson.prototype.constructor = GreetingPerson;
var manuel = new GreetingPerson();
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson();
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel._name);
But I'm not pretty sure if this is actually ok. The problem is that if you don't do something like Person.call(this); inside the constructor of GreetingPerson, you will not create a new instance of Person and it will always use the same _name value.
Check out Eloquent Javascript if you have time. I think this code should work for your purposes of inheritance.
function Person() {
var _name
this.setName = function(name) {
_name = name
}
this.getName = function() {
return _name
}
}
function GreetingPerson() {
Person.call(this);
this.sayHello = function() {
console.log(this.getName() + ': "Hello!"');
}
}
// taken from Eloquent Javascript
function clone(object) {
function OneShotConstructor() {}
OneShotConstructor.prototype = object;
return new OneShotConstructor();
}
GreetingPerson.prototype = clone(Person.prototype);
GreetingPerson.prototype.contructor = GreetingPerson;
var manuel = new GreetingPerson()
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson()
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel.name)​;​

Categories