Why aren't both variables undefined? - javascript

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;
}

Related

prototype and setTimeous

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

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');
}
});

Javascript Singleton communication definition required

I made a object to keep my functions became singleton, using that, i made sample methods to call and communicate each other.. but i don't get any appropriate results..
any one correct me, the singleton the way i defined here...
my sample codes:
var obj = window[obj] || {}; //singleton
obj.nameIt = function(name){
this.name = name;
this.getName = function(){
return this.name;
}
}
obj.sayIt = function(name){
this.name = name; var that = this;
this.sayHello = function(){
console.log("say" + this.name);
that.getName();//how to get result from nameIt?
}
}
var x = obj.nameIt("af");
console.log(x.getName());//says "undefined" - how to call it?
var y = obj.sayIt("xy");
console.log(y.sayHello());//says "undefined" - how to call it?
jsfiddle here
Your code does not return anything.
obj.nameIt = function(name){
this.name = name;
this.getName = function(){
return this.name;
}
return this;
}
obj.sayIt = function(name){
this.name = name; var that = this;
this.sayHello = function(){
console.log("say" + this.name);
return that.getName();
}
return this;
}

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 () { ... },
}
}

JavaScript prototypal inheritance: succinct syntax?

Is there a more succinct way to express this than three distinct, procedural operations? Something more object notation-like, or at least all within the body of the Name function?
Problem:
function Name(first, last) {
this.first = first;
this.last = last;
}
Name.prototype = new String;
Name.prototype.toString = function() {
return this.last + ', ' + this.first;
};
Test:
console.log(new Name("jimmy", "dean").toString())
console.log(new Name() instanceof Name);
console.log(new Name() instanceof String);
console.log(new Name() instanceof Object);
console.log(Name.prototype.toString.call(new Name('jimmy', 'dean')));
console.log(Name.prototype.toString.call({
first: 'jimmy',
last: 'dean'
}));
Expected output:
< "dean, jimmy"
< true
< true
< true
< "dean, jimmy"
< "dean, jimmy"
Example
function Name(first, last) {
this.partFirst = first;
this.partLast = last;
this.valueOf = this.toString = function() {
return this.partLast + ', ' + this.partFirst;
}
}
Name.prototype = new String();
Here's how I do it:
function subclass(constructor, superConstructor) {
function surrogateConstructor() { }
surrogateConstructor.prototype = superConstructor.prototype;
var prototypeObject = new surrogateConstructor();
prototypeObject.constructor = constructor;
constructor.prototype = prototypeObject;
}
/* Base object */
function BaseItem() {
this.type = 'baseitem';
this.obj = null;
}
BaseItem.prototype.render = function() {
return "foo";
}
/* Sub class */
function InteractionArea() {
BaseItem.call(this);
this.type = 'interactionarea'
this.obj = document.createElement('div')
}
subclass(InteractionArea, BaseItem);
//here come the overrides
InteractionArea.prototype.render = function() {
return "foobar";
}
InteractionArea.prototype.render2 = function() {
return "foobar";
}
/* Sub-sub class */
function InteractionArea2() {
InteractionArea.call(this);
this.type = 'interactionarea2';
this.obj = false;
}
subclass(InteractionArea2, InteractionArea);
InteractionArea2.prototype.render = function() {
return "bar";
}
Sure. Use Object.create.
var Name = Object.create(String.prototype, {
toString: { value: function _toString() {
return this.partLast + ', ' + this.partFirst;
} },
constructor: { value: function _constructor(first, last) {
this.partFirst = first;
this.partLast = last;
return this;
} }
});
var name = Object.create(Name).constructor("foo", "bar");
Now ES5 is a bit ugly, so you can use some mechanism for ES5 OO sugar, let's take pd as an example:
var Name = pd.make(String.prototype, {
toString: function _toString() {
return this.partLast + ', ' + this.partFirst;
},
constructor: function (first, last) {
this.partFirst = first;
this.partLast = last;
},
beget: pd.Base.beget
});
console.log(Name.beget("jimmy", "dean").toString())
console.log(Name.isPrototypeOf(Name.beget()));
console.log(String.prototype.isPrototypeOf(Name.beget()));
console.log(Object.prototype.isPrototypeOf(Name.beget()));
console.log(Name.toString.call(Name.beget('jimmy', 'dean')));
console.log(Name.toString.call({
partFirst: 'jimmy',
partLast: 'dean'
}));
Of course output is as expected Live Example

Categories