prototype and setTimeous - javascript

setTimeout doesn't work in the code below.
How can I fix it?
function Human(name, surname, sex) {
this.name = name;
this.surname = surname;
this.sex = sex;
};
Human.prototype.wash = function() {
console.log(this.sex + ' ' + this.name + this.surname + ' ' + 'takes a cleaner and start washing')
}
Human.prototype.washing = function() {
var that = this;
setTimeout(function() {
console.log(that.name + 'still washing...'), 3000
});
};
function Human1(name, surname, sex) {
Human.apply(this, arguments);
};
Human1.prototype = Object.create(Human.prototype);
Human1.prototype.constructor = Human1;
Human1.prototype.wash = function() {
Human.prototype.wash.apply(this);
Human.prototype.washing.apply(this);
console.log(this.name);
};
var Andrey = new Human1('Andrey', 'Balabukha', 'male');
Andrey.wash();

The timeout is in the wrong place. Should be:
Human.prototype.washing = function() {
var that = this;
setTimeout(function() {
console.log(that.name + 'still washing...');
}, 3000);
};

Related

Aliasing or otherwise merging two identical object prototypes with different names

I've got two object prototypes like this:
function Tag(name, description) {
this.name = name;
this.description = description || null;
}
function Category(name, description) {
this.name = name;
this.description = description || null;
}
Both of them are exactly the same, which seems awkward. Is it possible to merge them both into an object named 'Entity', and refer to them both by different names (the original 'Tag' and 'Category')?
This may be further complicated by the fact I need to refer to the current prototype name inside the prototype.
Tag.prototype.toJSON = function() {
return {
__type: 'Tag',
name: this.name,
description: this.description
};
};
How can I apply the same 'toJSON' extension to the 'Entity' object, but make sure it returns 'Tag' or 'Category' in the '__type' field, dependent on which object is being used?
I would do something like this:
Dummy = function () {};
Entity = function (name) {
this.name = name;
};
Entity.prototype.toString = function () {
return "My name is " + this.name + ".";
};
A = function () {
Entity.call(this, 'A');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = A;
A.prototype = new Dummy();
B = function () {
Entity.call(this, 'B');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = B;
B.prototype = new Dummy();
document.body.innerHTML = ""
+ (new A()) + "<br />"
+ (new B());
Here is a small function to make things cleaner (hopefully):
function Nothing () {};
function extend (Sup, proto) {
function Class () {
if (this.init) {
this.init.apply(this, arguments);
}
}
Nothing.prototype = Sup.prototype;
Nothing.prototype.constructor = Sup;
Class.prototype = new Nothing();
delete Nothing.prototype;
for (var k in proto) {
Class.prototype[k] = proto[k];
}
return Class;
}
Here is how to use it:
Entity = extend(Nothing, {
init: function (name) {
this.name = name;
},
toString: function () {
return "My name is " + this.name + ".";
}
});
A = extend(Entity, {
init: function () {
var sup = Entity.prototype;
sup.init.call(this, 'A');
}
});
B = extend(Entity, {
init: function () {
var sup = Entity.prototype;
sup.init.call(this, 'B');
}
});

Why aren't both variables undefined?

Why don't the lines console.log(VipUser); and console.log(DummyUser); both throw an error? Why don't both display "undefined" if you run this code in a
browser?
(function() {
var User = function(name, age) {
this.name = name;
this.age = age;
};
User.prototype.welcome = function() {
console.log('Welcome ' + this.name);
};
User.prototype.getAge = function() {
return this.age;
};
console.log(VipUser);
console.log(DummyUser);
function DummyUser(name, surname) {
this.name = name;
this.surname = surname;
this.toString = function() {
return this.name + ' ' + this.surname;
}
}
DummyUser.prototype.toString2 = function() {
return this.name + ' ' + this.surname;
}
var VipUser = function(name, age, memberId) {
};
}());
You need to move your console.log() like so:
(function() {
var User = function(name, age){
this.name = name;
this.age = age;
};
User.prototype.welcome = function(){
console.log('Welcome ' + this.name);
};
User.prototype.getAge = function(){
return this.age;
};
function DummyUser(name, surname) {
this.name = name;
this.surname = surname;
this.toString = function() {
return this.name + ' ' + this.surname;
}
}
DummyUser.prototype.toString2 = function() {
return this.name + ' ' + this.surname;
}
var VipUser = function(name, age, memberId){
};
console.log(VipUser);
console.log(DummyUser);
}());
See this jsfiddle
If you assign an anonymous function to a variable, then you cannot access it until after the assignment has been performed. In other words it is undefined before the assignment was made even if the anonymous function has already been 'compiled'.
From the fiddle:
console.log(x);
console.log(hello);
var x = function(t){
if(t){
return true;
}
return false;
}
function hello(r){
if(r){
return true;
}
return false;
}
console.log(x);
console.log(hello);
The output of the example code's first two logs is:
undefined
hello(r){
if(r){
return true;
}
return false;
}
then the second two logs output:
(t){
if(t){
return true;
}
return false;
}
hello(r){
if(r){
return true;
}
return false;
}

How to change value of the object's property

I have problem with understanding one aspect.
var Car = function(name, loc) {
'use strict';
this.name = name;
this.loc = loc;
this.methods = {
move: function() {
this.loc++;
},
show: function() {
console.log('Position of ' + this.name + ' is: ' + this.loc);
}
};
};
var amy = new Car('amy', 1);
var ben = new Car('ben', 9);
When I use this.loc++ it's referring to methods object, not to Car object. And location of car is not incremented. My question is how to jump to car object context from methods?
You can save parent context to variable (var _this = this;), like this
var Car = function(name, loc) {
'use strict';
var _this = this;
this.name = name;
this.loc = loc;
this.methods = {
move: function() {
_this.loc++;
},
show: function() {
console.log('Position of ' + _this.name + ' is: ' + _this.loc);
}
};
};
var amy = new Car('amy', 1);
var ben = new Car('ben', 9);
amy.methods.move();
amy.methods.move();
amy.methods.show();

Assigning a default value to a javascript using prototyping

I want to be able to assign default values to variables when I'm using prototyping for object creation.
When I try to assign default values to the variables they are always 'undefined'.
I have tried to find the answer but all the possible solutions I have tried dont work.
My questions are:
why do a variable that have I have initiated with a value has the value 'undefined'
how do I solve my problem?
(function() {
EmployeeNS = {};
EmployeeNS.Employee = function() {
var _firstName;
var _lastName;
var _employeeID = 'Unassigned';
}
EmployeeNS.Employee.prototype.setFirstName = function(fName) { this._firstName = fName; };
EmployeeNS.Employee.prototype.getFirstName = function() { return this._firstName; };
EmployeeNS.Employee.prototype.setLastName = function(lName) { this._lastName = lName; };
EmployeeNS.Employee.prototype.getLastName = function() { return this._lastName; };
EmployeeNS.Employee.prototype.setEmployeeID = function(employeeID) { this._employeeID = employeeID; };
EmployeeNS.Employee.prototype.getEmployeeID = function() { return this._employeeID; };
EmployeeNS.Worker = function() {
var _department;
}
EmployeeNS.Worker.prototype = new EmployeeNS.Employee();
EmployeeNS.Worker.prototype.constructor = Worker;
EmployeeNS.Worker.prototype.setDepartment = function(department) { this._department = department; };
EmployeeNS.Worker.prototype.getDepartment = function() { return this._department; };
})();
function createWorker() {
var x = new EmployeeNS.Worker();
x.setFirstName("John");
x.setLastName("Doe");
x.setDepartment("Transport");
var message = x.getFirstName()
+ " "
+ x.getLastName()
+ " (Department: "
+ x.getDepartment()
+ " / EmployeeID: "
+ x.getEmployeeID()
+ ")";
alert(message);
}
Thanks
you can simply make it to work by changing like this,
EmployeeNS.Employee = function() {
this._firstName;
this._lastName;
this._employeeID = 'Unassigned';
}
Try out this way , you can make those variables truly private by wrapping Employee ,
(function() {
EmployeeNS = {};
(function() {
var _firstName;
var _lastName;
var _employeeID = 'Unassigned';
EmployeeNS.Employee = function() {
}
EmployeeNS.Employee.prototype.setFirstName = function(fName) { _firstName = fName; };
EmployeeNS.Employee.prototype.getFirstName = function() { return _firstName; };
EmployeeNS.Employee.prototype.setLastName = function(lName) { _lastName = lName; };
EmployeeNS.Employee.prototype.getLastName = function() { return _lastName; };
EmployeeNS.Employee.prototype.setEmployeeID = function(employeeID) { _employeeID = employeeID; };
EmployeeNS.Employee.prototype.getEmployeeID = function() { return _employeeID; };
})();
(function() {
var _department;
EmployeeNS.Worker = function() {
}
EmployeeNS.Worker.prototype = new EmployeeNS.Employee();
EmployeeNS.Worker.prototype.constructor = Worker;
EmployeeNS.Worker.prototype.setDepartment = function(department) { _department = department; };
EmployeeNS.Worker.prototype.getDepartment = function() { return _department; };
})();
})();
Here is the jsfiddle
If you want instance properties, do it like this:
(function() {
EmployeeNS = {};
EmployeeNS.Employee = function () {
this._firstName = null;
this._lastName = null;
this._employeeID = 'Unassigned';
};
EmployeeNS.Employee.prototype.setFirstName = function(fName) {
this._firstName = fName;
};
})();

OOP Javascript - Accessing a privileged method from public method via another public method

var Person = function (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.scream = function () {
this.WhatToScream.screamAge();
}
Person.prototype.WhatToScream = function () {
this.screamAge = function () {
alert('I AM ' + this.age + ' YEARS OLD!!!');
}
this.screamName = function () {
alert('MY NAME IS ' + this.name + '!!!')
}
}
var man = new Person('Berna', 21);
man.scream();
// This code raises:
// Uncaught TypeError: Object WhatToScream has no method 'screamAge'
Here's a re-definiton that is closer to your original code:
Person.prototype.scream = function () {
new this.WhatToScream().screamAge();
}
var Person = function (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.scream = function () {
// get function screamAge from container WhatToScream,
// which is available in the instance of the object,
// because it was defined in the prototype
// and then call it with thisArg being current this,
// which is pointing to current container,
// * which at runtime is man
this.WhatToScream.screamAge.call(this);
}
Person.prototype.WhatToScream = {
screamAge: function () {
alert('I AM ' + this.age + ' YEARS OLD!!!');
},
screamName: function () {
alert('MY NAME IS ' + this.name + '!!!')
}
}
var man = new Person('Berna', 21);
man.scream();
If you want to keep WhatToScream as a function, you will need to call it to use the object it returns:
Person.prototype.scream = function () {
this.WhatToScream().screamAge.call(this);
}
Person.prototype.WhatToScream = function () {
return {
screamAge: function () { ... },
screamName: function () { ... },
}
}

Categories