JavaScript Puzzle I can't figure out - javascript

This is a kata for code wars, and I can't seem to figure it out. I have never worked with JavaScript before.
I know the answer is probably simple, but I just can't seem to figure out what they are looking for even after many hours of searching. I know that name in the greet function is not defined, but when I define it, it says it's not the value it's looking for.
function Person(name){
this.name = name;
}
Person.prototype.greet = function(otherName){
return "Hi " + otherName + ", my name is " + name;
}
Please help and an explanation would be greatly appreciated.

Don't really understand what you are looking for but hope this will shed some light : (try on your console)
function Person(name){
this.name = name;
}
Person.prototype.greet = function(otherName){
return "Hi " + otherName + ", my name is " + this.name;
}
var p = new Person('jack');
p.greet('sparrow');

Tyagi gave you an explanation of how to call it but did not show what the actual problem with the code is:
Here's my (very similar) example:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function (otherName) {
return "Hi " + otherName + ", my name is " + this.name;
}
var john = new Person("John");
$("#result").text(john.greet("Mike"));
and if you click through to this JSFiddle then you can see it actually working. The difference between the two is simply the change of "name" to "this.name" in the greet() function. You're attaching a new function to every Person object but it doesn't automatically look for the name variable on the object within that function the way it's defined.

I don't get your question but i will try to explain how it works:
// define a function (or class) called 'Person'
function Person(name){
// add data members 'name' to 'this' pointer which points to current context
this.name = name;
}
// define a method in 'Person' class
Person.prototype.greet = function(otherName){
//'othername' is an argument which you passed while calling 'greet' method
//'name' is an data memeber which you declared while creating 'Person' class
// will return value when you call this method
return "Hi " + otherName + ", my name is " + this.name;
}
// create a class object
var person = new Person('Mohit');
// call its 'greet' method
// will show an alert 'Hi Bekk, my name is Mohit'
alert(person.greet('Bekk'));
JSFiddle Link: http://jsfiddle.net/QqnL5/

Related

how to implement javascript inheritance

I'm looking into javascript inheritance for the first time, and I don't seem to be able to get it to work, or perhaps I'm not understanding it correctly.
So I have some code here, let's have a look at it:
<script language="javascript" type="text/javascript">
//object and prototype
function cat(name){//object constructor
this.name = name;//property
this.talk = function(){//method
console.log(this.name + " say meeow");
}
}
cat1 = new cat("Cat 1 Felix")
cat1.talk();
cat2 = new cat("cat 2 Joy")
cat2.talk()
//inheritance
function isleManCat(name){
cat.call(this,name)
this.feature = "no tail"
this.detail = function(){
console.log(this.name + " has " + this.feature);
}
}
isleManCat.prototype = new cat();
cat3 = new isleManCat("isle of Man cat")
cat3.talk();
cat3.detail();
</script>
So I have 2 cats objects here and cat1 and cat2 prints the expected results:
Cat 1 Felix say meeow
cat 2 Joy say meeow
. Then cat3 is a isleOfMan() cat which should inherit from cat(), and I would have thought that it would inherit the name property from cat() but it prints undefined:
undefined say meeow
undefined has no tail
Can somebody kindly let me know why it doesn't work and what i'm doing wrong please as I don't seem to understand that?
Thanks
Your third kitten deriving cat won't produce your expected result because the cat constructor won't be called by isleManCat's constructor auto-magically! And your third kitten has no name at all!
// You need to pass the name of the whole cat to this constructor
// to later give it as argument to base constructor (i.e. cat())
function isleManCat(name){
// This is calling cat constructor function setting the "this"
// keyword to the "this" of isleManCat
cat.call(this, name);
this.feature = "no tail"
this.detail = function(){
console.log(this.name + " has " + this.feature);
}
}
In ECMA-Script 5.x you can also use Function.prototype.apply and arguments reserved keyword to pass isleOfMan constructor's arguments as an array to cat:
function isleManCat(){
cat.apply(this, arguments);
this.feature = "no tail"
this.detail = function(){
console.log(this.name + " has " + this.feature);
}
}
And, in ECMA-Script 2015 and above, you can use rest parameters:
function isleManCat(...args){
// This is calling cat constructor function setting the "this"
// keyword to the "this" of isleManCat
cat.apply(this, args);
this.feature = "no tail"
this.detail = function(){
console.log(this.name + " has " + this.feature);
}
}

'this' and 'prototype', simple function

I am trying to resolve a problem but I need to understand prototype.
I was reading and I thought I got it, but I am still having some complications
function Person(name){
this.name = name;
}
Person.prototype.greet = function(otherName){
return "Hi " + otherName + ", my name is " + name;
}
var kate = new Person('Kate'); //name
var jose = new Person('Jose'); //otherName ???
so, is my mistake when I need to call the function ? or where is it ?
The name is a property of the object instance, so you need to use this.name in the greet method.
From what I understand, you need to display Hi Jose, my name is Kate like a greeting. In that case you need to pass the other person to the greet method then you can access that persons name using object.name
function Person(name) {
this.name = name;
}
Person.prototype.greet = function(other) {
return "Hi " + other.name + ", my name is " + this.name;
}
var kate = new Person('Kate');
var jose = new Person('Jose');
snippet.log(kate.greet(jose));
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Altering [object].prototype vs. [object]'s nested functions

This tutorial on prototypical inheritance uses the following code as an example of a Constructable object:
var Person = function (name) {
this.name = name;
};
var tom = new Person('tom');
But then goes on to say that if they want to change the Person object that tom was constructed with, then it should be done by altering Person.prototype:
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
But why does the prototype (which is Person) have to be altered? Why not just change Person directly like so:
Person.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
Is there a difference?
There is an important distinction to make between the function, and the object returned when treating the function as a constructor.
Person.say = function()
Isn't actually assigning a property to the function, which is it's own object, this has no effect on the generated objects, which inherit the prototype of the Person, overwritten with any changes made within the constructor call itself(hence why this.name still works).
var Person = function (name) {
this.name = name;
};
var tom = new Person('tom');
console.log(tom.__proto__);
// Object {}
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
console.log(tom.__proto__);
// Object {say: function}
When you call a method on tom if tom doesn't have the method it will look at the prototype, see if that has the method, you're not adding the method to tom ever, only the prototype it inherits from.
The following code binds the say function to the object prototype. When you create a Person instance, the function is called against the data in this instance.
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
The following code binds the say function to the object in a static fashion (thus, not available per-instance)
Person.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
The following alternative is this, which is a per-instance function, but is not bound to the prototype, rather the say function is created per instance, in the same way that name is created.
Just FYI, this method is NOT recommended (I'm just adding this for completeness) - It is recommended to bind your instance functions to the prototype:
var Person = function(name) {
this.name = name;
this.say = function(words) {
alert(this.name + " says " + words);
};
};
Prototype vs Per-instance:
Binding functions to the prototype (Person.prototype.say = function...) consumes less memory as one function is shared across all instances of the object.
Binding functions per-instance (this.say = function...) consumes more memory because a function is created for every instance created (nothing is shared), though this has the advantage of being able to access private members, which is not possible with prototype bound functions.
Overview:
Static binding: Person.say = function() { ... }
Prototype binding: Person.prototype.say - function() { ... }
Instance binding: function Person() { this.say = function() { ... } ... }
The difference is in memory occupation.
In your case using or not prototype does not change because you have only one istance of Person.
But if you create a lot of istance every istance will have own say function, instead with prototype the function will be shared.

What am I doing wrong with this prototype setup?

See the simplified code. What am I not getting with this pattern?
var john = new person('john');
john.hi();
function person(name) {
this.name = name;
}
person.prototype.hi = function() {
console.log('hi there. Name is ' + this.name);
};
If there's anything wrong it is the order of things. Other than that this seems correct.
function person(name) {
this.name = name;
}
person.prototype.hi = function() {
console.log('hi there. Name is ' + this.name);
};
var john = new person('john');
john.hi();
You could also add prototype function after the creation of your object, and this function can be called by all the instances, even those created before. Because when you call a function, the prototype chain will be searched if no function is found on your object itself.

Why does the greet function not return the expected value?

Question:
Why does the greet function not return the expected value?
Code:
function Person(name){
this.name = name;
}
Person.prototype.greet = function(otherName){
return "Hi" + otherName + ", my name is " + name;
}
How do I answer this? I create a new person then what do I do?
var John = new Person("John");
Wrong access method. the variable name isn't defined, only this.name is defined. So it's looking for a variable in the function scope called name instead of a property of the object called name.
To access an object's property from within the object we use the this keyword. Thus we'll need to use this.name to access the name property in the implementation below.
Person.prototype.greet = function(otherName){
return "Hi" + otherName + ", my name is " + this.name;
}
In your code:
> function Person(name) {
> this.name = name;
> }
When called as a constructor, the above will create a named property of an instance called name and assign it the value of the name parameter.
> Person.prototype.greet = function(otherName){
> return "Hi" + otherName + ", my name is " + name;
> }
Here the identifier name is used as a variable, but the identifier you are looking for is a named property of the instance, so you need to access it at as such. Typically, this function will be called as a method of the instance so this within the function will be a reference to the instance. So you want:
return "Hi" + otherName + ", my name is " + this.name;
So now when you can do (note that variables starting with a capital letter are, by convention, reserved for construtors):
> var john = new Person("John");
and then:
john.greet('Fred');
because greet is called as a method of john, it will return:
Hi Fred, my name is John
Alternatively, since this is an issue of scope inheritance (second function not having access to the variable "name"), we can rephrase the code to look like this to include it all under the Person function:
function Person(name){
this.name = name;
this.greet = function(otherName){
return "Hi" + otherName + ", my name is " + name;
}
}
Works as well.
You need to change the greet function to use the object's name with the this keyword:
Person.prototype.greet = function(otherName){
return "Hi" + otherName + ", my name is " + this.name;
}
after that, just call John.greet("other name");
Try the following:
function Person(name){
this.name = name;
this.greet = function(otherName){
return "Hi " + otherName + ", my name is " + name;
}
}
Person("Joe")
greet("Kate")

Categories