I am in the process of learning Javascript and came across the apply function. I thought I could assign my apply value to a variable and then print out the contents of the variable. However, I seem to get undefined and I'm not sure why this is happening...
var thisObj = {
fullName: 'test',
setName: function(firstName, lastName) {
this.fullName = firstName + " " + lastName
}
}
function getInput(firstName, lastName, callBack, createdObj) {
return callBack.apply(createdObj, [firstName, lastName]);
}
var thisObjectInstantiated = getInput("Michael", "Jackson", thisObj.setName, thisObj);
console.log(thisObjectInstantiated); // Why is this undefined?
I noticed also if I change the print to do something like this, my name is properly defined.
var thisObjectInstantiated = getInput("Michael", "Jackson", thisObj.setName, thisObj);
console.log(thisObj.fullName); // This is defined properly!
How come I can't just store the results of the apply within the thisObjectInstantiated variable? Thanks.
You are calling the getInput function, that is calling the setName function, that doesnt return nothing, so thisObjectInstantiated is receiving... nothing!
You would probably want to change your code like this:
var thisObj = {
fullName: 'test',
setName: function(firstName, lastName) {
this.fullName = firstName + " " + lastName;
return this;
}
}
You are assigning the result of the function call, in your code, no value is returned. That's why you get undefined.
The code executed without a return value, so the default return value by JavaScript is undefined
Related
I have been learning JS on my own and completed an 8 hour course on the basics. Now I am following another course where the lecturer, as it seems to me, is creating a function using dot notation. I am not sure if this is what is happening and I am having a hard time understanding exactly what it is doing.
function Person(fName, lName) {
this.firstName = fName
this.lastName = lName
}
const person1 = new Person("Bruce", "Wayne")
const person2 = new Person("Bat", "Man")
person1.getFullName = function () {
return this.firstName + ' ' + this.lastName
}
console.log(person1.getFullName())
The part I am confused about is:
person1.getFullName = function () {
return this.firstName + ' ' + this.lastName
}
I see in the Person() function we are creating an object called person1 using "this" and a key to pass in parameters as values for those keys. However it looks to me like there is a function being assigned to the person1 object and what I am assuming is the name of the function, looks like a method on the person1 object using dot notation. Can anyone explain how this works?
The line
person1.getFullName = ...
is a normal assignment statement. It assigns the value on the right hand side to the property getFullName of the object in person1. If the property doesn't exist yet it will be created.
Functions are values (objects) like any other in JavaScript and thus they can be used everywhere were a value is expected.
So yes, person1.getFullName will contain a function and it can be called like any other function: person1.getFullName().
Objects have properties.
Properties have values.
Functions are a value.
If the value of a property is a function then we call that a method.
That's all there is to it.
function Person(fName, lName) {
this.firstName = fName
this.lastName = lName
}
const person1 = new Person("Bruce", "Wayne")
const person2 = new Person("Bat", "Man")
person1.getFullName = function () {
return this.firstName + ' ' + this.lastName
}
console.log(person1.getFullName())
Basically a new property called getFullName is created for the object person1. This new property is defined to return the first name and the lastname of the person1 object. So when you call console.log(person1.getFullName()) this will print the firstname and the lastname of the person1.
So, I was thinking of creating a function which does some stuff, and later use the same function inside different objects created later.
In the code below are two instances: Testing (01) and commenting out (02), and vice versa.
"use strict";
function fullName() {
return this.firstName + " " + this.lastName;
}
const person = {
firstName: "Anant",
lastName: "Ghotale"
completeName: fullName.call(person) // (01) does not work
};
//person.completeName = fullName.call(person); (02) this works
console.clear();
console.log(person.completeName);
(02) works, but (01) doesn't.
That is to say, creating a new property outside person while using call to put this = person works, but not inside it.
These are my questions:
How do I use (call) a function inside an object?
Is this a foolish endeavour, to call a function inside an object? Is there a better way to do the same task?
You probably want to use a getter for this.
function fullName() {
return this.firstName + " " + this.lastName;
}
const person = {
firstName: "Anant",
lastName: "Ghotale",
get completeName() {
return fullName.call(this)
}
};
console.log(person.completeName)
I am practicing Javascript object function. Supposed I have firstName and lastName as two arguments of my function.I want to display like this {"firstName":"tim","lastName":doe} . Here is my code but it printed out undefined. Any idea? Thank you!
function myFunction(firstName, lastName) {
this.name1 = firstName;
this.name2 = lastName;
}
var obj = new myFunction();
console.log(myFunction('tim', 'doe'));
Try this:
console.log(new myFunction('tim', 'doe'));
Or this:
console.log(obj);
You can try this
function myFunction(firstName, lastName) {
this.name1 = firstName;
this.name2 = lastName;
}
var obj = new myFunction('tim', 'doe');
console.log(obj);
You can see this documentation JavaScript Constructors
This kind of function called constructor, and you shouldn't call it directly. You have to use it with new.
console.log(new myFunction('tim', 'doe'));
This will print the result as you expect.
To distinguish the constructors from normal functions, it's better to name it begin with capital letter, like this:
function MyFunction(...) {...}
the undefined you receive is from the function not having a return value, see this post regarding that:Simple function returning 'undefined' value
to get the result you want...
function myFunction(firstName, lastName) {
this.name1 = firstName;
this.name2 = lastName;
}
var obj = new myFunction('tim', 'doe');
console.log(obj);
Let's explore what this line does: console.log(myFunction('tim', 'doe'));
This part: myFunction('tim', 'doe') executes myFunction as a function. Since myFunction does not have a return operator, it's return value is 'undefined' which is javascript's way of saying it doesn't exist. Thus, the word 'undefined' is printed on the console.
Additional tips:
Try adding this line: console.log(typeof myFunction);
This should print 'function'.
(May the 'typeof' operator become your best friend)
Try adding a return line as the last line of myFunctions such as:
return 'First name: ' + firstName + " Last name: " + lastName;
However, at this point the 'var obj = new myFunction();' line is unused.
Try adding another line:
console.log(typeof obj);
This should print 'object' which means that 'obj' is just that - an object.
Here is a complete example you can play with:
function myFunction(firstName, lastName) {
this.name1 = firstName;
this.name2 = lastName;
this.getNames = function() {
return 'First name: ' + firstName + " Last name: " + lastName;
}
console.log("This executes once upon instatiation (the line with var obj = new ...)");
return "Return value";
}
var obj = new myFunction('tim', 'doe');
console.log(typeof myFunction);
console.log(typeof obj);
console.log(obj.getNames());
Let me know if any of the above needs clarification. Good luck ...
BTW, this is what the output should look like on the console:
This executes once upon instatiation (the line with var obj = new ...)
script.js:14 function
script.js:15 object
script.js:16 First name: tim Last name: doe
I have a question in respect of the js constructor function. I have the following code:
var PersonConstructorFunction = function (firstName, lastname, gender) {
this.personFirstName = firstName;
this.personLastName = lastname;
this.personGender = gender;
this.personFullName = function () {
return this.personFirstName + " " + this.personLastName;
};
this.personGreeting = function (person) {
if (this.personGender == "male") {
return "Hello Mr." + this.personFullName();
}
else if (this.personGender == "female") {
return "Hello Mrs." + this.personFullName();
}
else {
return "Hello There!";
}
};
};
var p = new PersonConstructorFunction("Donald", "Duck", "male");
p2 = new PersonConstructorFunction("Lola", "Bunney", "female");
document.write(p2.personGreeting(p2) + " ");
The result is quite obvious - --Hello Mrs. Lola Bunney--
The question is:
There are two equivalent objects p and p2 with the same number of properties and methods. I can't understand the following behaviour when I call the personGreeting method of one object and pass the second object as the argument:
**document.write(p2.personGreeting(p) + " ");**
in this case I get --Hello Mrs. Lola Bunney-- but what about the p object that is passed as the argument?
personGreeting gets the person object, determines their gender and bsed on the result shows appropriate greetings.
Resently I learned C# and constructors there works similarly I guess.
You are not doing anything with the passed parameter. Since you are utilizing this only the variables that are within your constructor are being called.
You COULD do person.personFullName(); and that would mean that the parameters member personFullName() would be called and not your constructors.
I basically having hard times understanding why I cannot overwrite an object property when using inheritance from another object, it goes like this.
var Person = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
Object.defineProperties(Person.prototype, {
sayHi : {
value :function() {
return "Hi there";
},
enumerable : true,
writable : true
},
fullName : {
get : function() {
return this.firstName + " " + this.lastName;
},
enumerable : true
}
});
var createEmployee = function(firstName, lastName, ocupation) {
var employee = new Person(firstName, lastName);
employee.ocupation = ocupation;
Object.defineProperty(employee, "sayHi", {
sayHi : {
value : function() {
return "Hey I am " + this.firstName;
}
}
});
return employee;
};
var janeDoe = createEmployee('Jane', 'Doe', 'Actress');
So, accoding to what I understand, I should overwrite the sayHi property on the employee object, however, I get it as undefined.
Could please some1 show me money?
here is the jsfiddle
Best Regards.
You could use the outdated Object.defineProperty() or the Object.assign(). However, there's a cleaner, more modern solution to this.
Simply do:
objectName = {...objectName, property: "newvalue"};
// or
objectName = {property: "newvalue", ...objectName};
the difference between the two is that the first will overwrite the property named property, while the second will create a new property called property and assign a value, however, it won't overwrite it if it already exists.
Take a look at JS spread syntax for more info.
Such could also be done for setting your prototype:
Person.prototype = {...Person.prototype, sayHi: _=>"Hi there!"};
Just realized the answer I gave was bad.
You don't need the name inside the object there.
Object.defineProperty(employee, "sayHi", {
sayHi : {//<- don't need this.
value : function() {
return "Hey I am " + this.firstName;
}
}//<- or this.
});
Try this:
Object.defineProperty(employee, "sayHi", {
value: "Hey I am " + employee.firstName
});
Also, Mozilla's explanation on Object.defineProperty() is quite excellent, you should check it out.