Console prints out undefined. What is wrong with my code? - javascript

function Person(name,age){
this.name=name;
this.age=age;
}
var person1 = new Person("name1",4)
var person2 = new Person("name2",6)
function Animal(name,size){
this.name=name;
this.size=size;
}
var animal1=new Animal("name1","small")
var animal2 = new Animal("name2","big")
Person.prototype.sayName=function(){
console.log("Hello "+[name])
}
Animal.prototype.sayName=function(){
console.log("Hello "+[name])
}
animal1.sayName();
I just learned Javascript and I started playing around with some code. When I run this code, the console prints out undefined. I believe the console should print : "Hello animal1". What is wrong with it?

In javascript, when you say new, first thing that would happen is that an empty object would be created. Upon the creation of this object, the animal function is executed and the current execution context would be referring to newly created empty object. So when you say this.name = name and this.size = size, the this keyword would be referring to the newly created object. So you need to always reference the property with this, while accessing it as shown in the below snippet:
function Animal(name,size){
this.name=name;
this.size=size;
}
var animal1=new Animal("name1","small")
Animal.prototype.sayName=function(){
console.log("Hello "+this.name)
}
animal1.sayName();
Hope this answers your question

you have to specify the this keyword to refer to the current instance.
Animal.prototype.sayName = function(){
console.log("Hello "+ this.name)
}

console.log("Hello " + [name]) should be console.log("Hello " + this.name)
I tried it in my console, now it outputs Hello name1.

Related

"this" is different when function called from local function object

I wrote the following code, where I would expect the calls to getFull() and useGetFull() to do the same thing, since useGetFull just gets a function object for getFull() and calls it.
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
const f = this.getFull;
f();
// f.call(this) works as expected
}
p = new Person("Bob", "Smith");
p.getFull();
p.useGetFull();
However, they don't do the same thing, because inside useGetFull(), "this" is the global object. I noticed that using f.call(this) instead of f() works as intended, but I can't wrap my head around why I have to use it. Why is the value of "this" different depending on how/where I call the function?
A simple rule:
a.b() //b called with context a
d.e() //e called with context d
c() // c called with no context ( so the global instead)
Javascripts context depends on how the function was called.
If you haven't noticed, this.getFull() also works. This is because when you invoke the function as a property of an object (any object), that function's this will refer to that object, the object you invoked the function on, in case of foo.bar(), foo, and in case of this.getFull(), this. This is why this example works as expected:
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
/* getFull is preceded by something, it is invoked through "this", so
the "this" reference inside of getFull will be set to the "this" part in
the statement "this.getFull()". */
this.getFull();
}
p = new Person("Bob", "Smith");
p.getFull(); prints out Bob Smith
p.useGetFull(); // prints out Bob Smith
However, when a function is invoked not as the property on an object, in other words, when it is not accessed in a way similar to either foo.bar() or foo["bar"](), but in a way like foo(), even if foo is a reference to a variable whose value is x.y, like f() in your example, its this will be bound to the global object, in a browser, that object is window.
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
const f = this.getFull;
/* this call is not preceded by any objects, it is a plain
traditional function call, it is a function invokation in its
simplest form. all functions invoked in this manner will have
their "this" reference set to the global object. */
f();
}
p = new Person("Bob", "Smith");
p.getFull();
p.useGetFull();
If you are interested in this (pun not intended), go here.

JavaScript Prototype browser output

This is a code the works fine in Codecademy which is where it's from. However, when I try the same code in the browser, it keeps returning undefined.
<script>
function Cat(name, breed) {
this.name = name;
this.breed = breed;
}
Cat.prototype.meow = function() {
console.log('Meow!');
};
var cheshire = new Cat("Cheshire Cat", "British Shorthair");
var gary = new Cat("Gary", "Domestic Shorthair");
alert(console.log(cheshire.meow));
alert(console.log(gary.meow));
</script>
You're passing the result of console.log() to alert but it doesn't return anything so you're passing undefined to alert.
Either use only alert or only console log, don't pass one to the other.
Your meow function already logs to the console, so doing it again is pointless. Most likely what you want is this:
cheshire.meow();
gary.meow();
Note that since meow is a function, you probably want to actually call it and not just print the function itself.

Why the console output undefined? [duplicate]

This question already has answers here:
Why does this JavaScript code print "undefined" on the console?
(1 answer)
Why does the JS console return an extra undefined? [duplicate]
(1 answer)
Closed 8 years ago.
I have code following like this:
function Person() {
this.name = '123';
this.age = 123;
}
Person.prototype.load = function() {
console.log(this.name + " test ");
}
var p1 = new Person();
console.log(p1.load());
the console output two news. One is 123 test, the other is undefined.I wonder where is undefined comes from?
The load functions returns nothing, that is it returns undefined. And you log this undefined here :
console.log(p1.load());
You probably just want
p1.load();
The return value of console.log is ALWAYS undefined. It prints to the console, but it doesn't actually return anything itself.
var tmp = 5;
console.log(tmp); // prints 5, returns undefined.
tmp; // Returns 5
Also why are you printing out the result of a function that already prints out the information you want?
hi you do not need to take too much tension about that undefined. Your code is correct and it will work fine in any js file.
That undefined comes as you make instance of person class.
http://jsfiddle.net/5azsp5r9/
Here you go mister:
function Person() {
this.name = '123';
this.age = 123;
}
Person.prototype.load = function() {
//Load started for John Doe
console.log("Load started for "+ this.name );
return "Load ended";
}
var p1 = new Person();
p1.name = "John Doe";
//Load ended
console.log(p1.load());;

javascript - call prototype method from inside the base method

How can I call a prototype function from the object's main function/constructor in javascript. I tried the following, but it does not work. What am I doing wrong?
var x = new myFunction('Hello World!');
function myFunction(name) {
this.name = name;
alert( toString() ); // not working
alert( this.toString() ); // not working either
};
myFunction.prototype.toString = function() {
return 'My name is ' + this.name;
};
You're creating an instance of myFunction and call toString on it before you set the prototype.
The reason you can create an instance of myFunction even before you declare it is because it was hoisted. toString is not hoisted however and it would show [Object object].
Solution is to create instances after you fully declare the object.
Note: A constructor function should start with a capital so it should be MyFunction instead of myFunction and maybe give it a name that actually means something like Person or Animal since nobody would have a clue to what a MyFunction is.
function myFunction(name) {
this.name = name;
//console.log is so much better than alert
console.log('this is:',this,'this.toString:'
, this.toString() );
};
myFunction.prototype.toString = function() {
return 'My name is ' + this.name;
};
var x = new myFunction('Hello World!');
More on prototype here: Prototypical inheritance - writing up

Implementing instance members/methods in JavaScript

This question stems from a problem I was trying to solve regarding the ability to have "private" instance variables in JavaScript. You may want to read this, prior to my question.
For the sake of completeness, I have illustrated my entire problem, before asking the question. My hope is that this will provide a complete example of how to implement instance members and methods correctly in JavaScript, and for any developer who lands here, to understand the pitfalls of the various implementations.
Consider the following JavaScript object:
var MessageBox = (function() {
function MessageBox(message) {
this.message = message;
}
MessageBox.prototype.Show = function() {
alert(this.message);
}
})();
This object was modelled using TypeScript, and can be used as follows:
var msg1 = new MessageBox("Hello World");
msg1.Show(); // alerts "Hello World"
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
But I can still call:
msg1.message; // "Hello World"
msg2.message; // "Bye World"
So clearly this.message is NOT private.
Now consider the following JavaScript object:
var MessageBox = (function() {
return function MessageBox(message) {
var message = message;
MessageBox.prototype.Show = function() {
alert(message);
}
}
})();
This is just a modified version of the TypeScript based MessageBox object.
var msg1 = new MessageBox("Hello World");
msg1.Show(); // alerts "Hello World"
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
but wait...I'm about to throw a spanner in the works!
var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
msg1.Show(); // alerts "Bye World" ... wait, what!?
msg1.message // undefined
msg2.message // undefined
So I can no longer gain access to the message variable, but now, every new instance overwrites the last instances message.
Bear with me, this is the last JavaScript object to consider:
var MessageBox = (function() {
return function MessageBox(message) {
var message = message;
this.Show = function() {
alert(message);
}
}
}();
The above object no longer implements Show() on the prototype, so now I can:
var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
msg1.Show(); // alerts "Hello World"
msg1.message // undefined
msg2.message // undefined
Great! Now I have private variables, and they don't overwrite each other!
So, finally the question: What is the difference between:
MessageBox.prototype.Show = function() {
}
and
this.Show = function() {
}
The question that you eventually get to has a simple answer: setting the function on the prototype means it can get called from any instance, while setting the function on the instance means it can be called only from that instance. Either way can access properties on the instance, but the thing that you're finding complicated is that either way the function only has access to local variables in the scope where it was declared or in containing scopes.
The following is the first way that came to mind to provide both private instance and private prototype variables.:
var MessageBox = (function() {
var privateProtoVar = "Hello";
function MessageBox(message) {
var privateInstanceVar = message;
this.instanceMethod = function() {
alert(privateInstanceVar); // Can access private instance var
alert(privateProtoVar); // Can access private prototype var
}
}
MessageBox.prototype.Show = function() {
alert(privateProtoVar); // Can access private proto var
// but can't access privateInstanceVar
}
return MessageBox;
})();
var msg1 = new MessageBox("1"),
msg2 = new MessageBox("2");
msg1.instanceMethod(); // "1", "Hello"
msg2.instanceMethod(); // "2", "Hello"
msg1.Show(); // "Hello"
msg2.Show(); // "Hello"
The variable privateInstanceVar is accessible by any function declared inside the inner MessageBox() function, but not from functions on the prototype unless they're declared within that same scope (which I don't do in the above example).
If you add additional methods to instances later, i.e., outside the above structure then those methods do not have access to the private var because they're declared in a different scope:
msg1.newMethod = function() {
alert(privateInstanceVar);
}
msg1.newMethod(); // error
Demo: http://jsfiddle.net/SSEga/
With MessageBox.prototype.Show you are overriding the Show function for any instance every time you call new MessageBox(). Therefore every instance always shares the same Show function with the same scope.

Categories