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

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?

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());

Function coming back undefined in 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/

In OPP JS can you access a method declared inside a prototype function from the constructor?

I'm reading about OPP js and while going over an example and was wondering if in:
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
var tempName = this.name;
var saySomething = function(){
console.log(tempName);
}
//return saySomething();
}
var person1 = new Person('chris');
is theres a way to fire the saySomething method from the constructor.
eg.
person1.sayName().saySomething() //which doesnt work obviously
Returning an object when sayName will work:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
var tempName = this.name;
return {
saySomething: function() {
console.log(tempName);
}
};
};
var person1 = new Person('chris');
person1.sayName().saySomething(); // logs 'chris'

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)​;​

In Javascript, how do I loop through objects inherited from a given constructor?

In something like the following example, how would I go about looping over every object from the apple prototype?
function apple(id,name,color) {
this.id = id;
this.name = name;
this.color = color;
}
apple1 = new apple(0,"Golden Delicious","Yellow");
myapple = new apple(1,"Mcintosh","Mixed");
anotherapple = new apple(2,"Bramley","Green");
/*
for each instance of apple {
if (this one is "Green") { do something }
}
*/
I'd use something like static property that contains references to all instances. You'll add every instance there in the constructor:
function apple(id,name,color) {
this.id = id;
this.name = name;
this.color = color;
apple.instances.push(this);
}
apple.instances = [];
Then, you can loop through apple.instances.
I am using capitalized name for constructor so the syntax highlighter gets it:
function Apple(name,color) {
this.name = name;
this.color = color;
this.id = this.constructor.getId();
this.constructor.instances[this.id] = this;
}
Apple.instances = {};
Apple.getId = (function(){
var i = 0;
return function(){
return i++;
};
})();
/* ... */
var instance, key;
for( key in Apple.instances ) {
instance = Apple.instances[key];
if( instance.color == "green" ) {
delete Apple.instances[instance.id];
}
}

Categories