simple "this" issue with JavaScript fundamentals - javascript

var name = 'Mike';
var person = {
name: 'John',
welcome: function(){
var name = 'Mary';
return 'Hi ' + this.name;
}
}
//person.welcome();
// output is
// Hi John
// I was expecting output to be
// Hi Mary
person.welcome.call();
// output is
// Hi Mike
// In this case since no argument is passed to call so this is window and
// I get that window.name is Mike

var name = 'Mike';
var person = {
name: 'John',
welcome: function(){
var name = 'Mary';
return 'Hi ' + this.name;
}
}
this.name refers to the object property "name"
name refers to the variable "name"
You would get the expected result with return 'Hi ' + name;

Why were you expecting Hi Mary in the first case?
var name = 'Mary';
Doesn't overwrite this.name, but rather creates a local variable named name in the function.
In the second case, you are using call, which takes a this argument, and:
Determines the value of this inside
fun. If thisArg is null or undefined,
this will be the global object.
From here.

this always refers to the object you are calling the function from. In most simple cases this would be whatever is in front of the .. For example, in the case of person.welcome() this now refers to person. If you call person.welcome.call() this refers to the window, because you did not specify anything as a parameter to call().

If you are waiting the output to be Hi Mary then you do not need to use this in the welcome function. This should do it:
var name = 'Mike';
var person = {
name: 'John',
welcome: function(){
var name = 'Mary';
return 'Hi ' + name;
}
}
When you do person.welcome() the this keyword references person, so on the welcome function this.name would become person.name which is John.

Related

Method Syntax in Object Literal notation?

I'm new to JavaScript and I'm having a little trouble with execution context; the value of this.
Consider the following:
const name = "Mary";
const proto = {
hello: () => `Hello, my name is ${ this.name }.`
};
const greeter = name => Object.assign(Object.create(proto), { name });
const joe = greeter("Joe");
console.log(joe.hello());
I expected the log would be: Hello, my name is Joe. But this was instead the global object. It returned Hello, my name is Mary.
On the other hand:
const name = "Mary";
const proto = {
hello() { return `Hello, my name is ${ this.name }.` }
};
const greeter = name => Object.assign(Object.create(proto), { name });
const joe = greeter("Joe");
console.log(joe.hello());
This time the expected string was returned; the only difference is the "method definition" inside the proto object.
So my question is what is the second syntax even called?
It is not a function declaration nor a function expression, so what is it? Either way I expected the property accessor invocation from the 'greeter' object, 'joe' to associate this to the object itself.
And when should I use a function expression and when should I use this alternative form of declaring an object's method?
I hope this makes sense and thank you in advance for you attention.

Methods, Loops and the `this` Keyword

I am new at Javascript. I am currently looking at the keyword this and methods and how to return strings.
I am struggling to return a string using the keyword this.
I have successfully created code that returns the string, but the problem is that it shows the error that "the object is already defined".
Here is the exercise I am working on and also the code I have tried to create which fails to return the correct results:
function exerciseTwo(userObj) {
// Exercise Two: You will be given an object called 'userObj'
// userObject will already have a key on it called 'name'
// Add a method to userObj, called 'greeting'.
// Using the keyword 'this', the greeting method should return the following string:
// 'Hi, my name is ' and the users name.
// eg: If userObj has a name: 'Dan', greeting should return: Hi, my name is Dan'
// NOTE: DO NOT create a new object.
// NOTE: DO NOT create a key called name the key is already on the object.
let userObj = {
name: "Lisa",
greeting: function() {
return "Hi, my name is " + this.name;
},
};
console.log(userObj.greeting());
}
//In the first line of code it shows a error which says that "userObj" is already defined. So I do not know how to return the string without creating a new object and creating a key called name.
//Here is another option I tried but it also did not work out:
function greeting() {
this.name = "Lisa";
let result = "Hi, my name is " + this.name;
return result;
},
userObj.greeting();
}
//The exercise should add a greeting method to userObject object.
So if userObj has a name: 'Lisa', greeting should return: 'Hi, my name is Lisa'
The problem is that your local variable has the same name as the function parameter. You're supposed to add a method to the existing variable, not create a new variable. The instructions specifically say "DO NOT create a new object", yet that is what you did.
function exerciseTwo(userObj) {
// Exercise Two: You will be given an object called 'userObj'
// userObject will already have a key on it called 'name'
// Add a method to userObj, called 'greeting'.
// Using the keyword 'this', the greeting method should return the following string:
// 'Hi, my name is ' and the users name.
// eg: If userObj has a name: 'Dan', greeting should return: Hi, my name is Dan'
// NOTE: DO NOT create a new object.
// NOTE: DO NOT create a key called name the key is already on the object.
userObj.greeting = function() {
return "Hi, my name is " + this.name;
};
console.log(userObj.greeting());
}
let obj = {
name: "Joe"
};
exerciseTwo(obj);
function exerciseTwo(userObj){ // The argument for this "exerciseTwo" function has been declared as "userObj"
let userObj = { // Here you are trying to declare another variable "userObj"
name: "Lisa",
greeting: function() {
return "Hi, my name is " + this.name;
}
};
console.log(userObj.greeting());
}
To solve your issue,
- Declare the let userObj = { ... } block outside the "exerciseTwo" function and pass it in as a variable
let lisa = {
name: "Lisa"
};
function exerciseTwo(userObj){ // Whatever variable you pass into this function will be synonymous to `userObj` within this function
userObj.greeting = function () {
return "Hi, my name is " + this.name;
}
console.log(userObj.greeting());
}
exerciseTwo(lisa) // lisa will take the position of `userObj` above
As the exercise says you only have to add the greeting function to the users object. Like this:
let userObj = { name: "Lisa" };
function exercise2(userObj) {
userObj.greetings = function () {
return "Hi, my name is " + this.name;
}
}
exercise2(userObj);
console.log(userObj.greetings());

How to add 'this' to a object in Javascript?

So I created the greeting method, but I am having trouble trying to return the string with the this method. All help would be greatly appreciated please.
function exerciseTwo(userObj){
// Exercise Two: You will be given an object called 'userObj'
// userObject will already have a key on it called 'name'
// Add a method to userObj, called 'greeting'.
// Using the keyword 'this', the greeting method should return the following string:
// 'Hi, my name is ' and the users name.
// eg: If userObj has a name: 'Dan', greeting should return: Hi, my name is Dan'
// NOTE: DO NOT create a new object.
// NOTE: DO NOT create a key called name the key is already on the object.
userObj.greeting = 'Hi, my name is ' + this.name;
return userObj;
}
If you run the function without creating any new objects and call the function, this will have the scope of where you call the function from, which will be window, so you can either create a var name with the value 'users name' or set a property on window directly with window.name = 'users name';
this in JavaScript is a bit loopy.
var name = 'Dan';
console.log(window.name);
function exerciseTwo(userObj){
userObj.greeting = 'Hi, my name is ' + this.name;
return userObj;
}
console.log(exerciseTwo({}));
In the browser DOM you have a window object that is the namespace for everything the page does, so calling exerciseTwo when you are not in an object, this will resolve to window. All variables you create without a namespace will be attached to the window object.
var userObj = { // An object with the name property as Dan
name: 'Dan'
}
userObj.greeting = function () { // Adding a function to the object called greeting
return 'Hi, my name is ' + this.name;
}
console.log(userObj.greeting());
In this instance, when the function is called this has the scope of the object userObj.

Why isn't my object private when my variable is?

I'm trying to make a object private, but not sure how to do that. As you can see the name variable is private, I can't edit it but when it comes to the object that I return, I can edit. I dont want that to be possible, though.
I quite new to object-oriented and private methods in javascript, so could someone tell me what's right and wrong here. :) How can I solve this?
Thanks!
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return otherInfo;
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
Primitive values such as Strings are passed by value. This means when you assign a String to your variable, you are setting the actual value of the String to the variable.
Objects are passed by reference. This means when you assign an Object to your variable, you are simply making a reference to the Object, not it's actual value. If you had one Object and assigned it to 6 different variables, each variable would have a reference to the same underlying Object.
In your example, your getOther method is returning a reference to the otherInfo object. So when you set the age property to "wtf", you are setting it on the Object that your variable refers to.
You also declare var name twice.
When you var person = new User(); a var name is declared within the scope of the User function.
When you var name = person.getName(); you are declaring a variable with the same name outside the scope of the User function.
So, when you name = 'Jenny'; the interpreter associates this string the name variable outside the scope of User.
In general, it is a bad idea to use such variables with common names (name, title, id, ...) as global variables. I would refer to the object attributes with this. and define setters as well as getters. You can also ignore the setters and refer to the User attributes with person., like this:
function User() {
this.name = 'bob';
this.getName = function() {
return this.name;
}
this.otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return this.otherInfo;
}
}
var person = new User();
console.log(person.getName()); // bob
person.name = 'jenny';
console.log(person.getName()); // jenny
console.log(person.getOther(); // { age: 20, human: true }
person.otherInfo.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
You don't have “private” things in object scope in Javascript. The only way to hide things from the outside is with a function scope, like you did with name (a local variable in the function User).
To return an object with the same content every time, you could make the object inside the function. Like this, for instance:
this.getOther = function() {
var otherInfo = {
age: 20,
human: true,
}
return otherInfo;
}
Or just:
this.getOther = function() {
return {
age: 20,
human: true,
};
}
In both cases, you will be creating a new object with every call.
It is happen, because in JS object passes by link - there are not coped from source object.
Just try copy object:
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return Object.assign({}, otherInfo);
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 20, human: true }

New Object Creation issues

Ok so the following function acts as a constructor to create an Employee object(no problem with that). But when I use this function to create 3 new employees I am messing up somewhere.
I know I'm supposed to set the properties and print the employee's name and phone number, but I am missing something or something is in the wrong place.
Thanks in advance for your help.
function Employe() {
var = name;
var = phone;
this.getName = function () {
return this.name;
}
this.setName = function (name, phone) {
this.name = name;
this.phone = phone;
};
}
var emp1 = newEmployee;
this.Name = 'jo';
this.Phone = ' 555-5551'
document.write(Employee.name Employee.phone);
var emp2 = newEmployee;
this.Name = 'jim';
this.Phone = '555-5552';
document.write(Employee.name Employee.phone);
var emp3 = newEmployee;
this.Name = 'jon';
this.Phone = '555-5553';
document.write(Employee.name Employee.phone);
In the following:
> var emp1 = newEmployee;
The variable on the left will be assigned the result of evaluating the expression on the right. There is no identifier newEmployee, so you will get an error. What you probably meant to write is:
var emp1 = new Employee();
That will call the constructor, which will return a new instance, a reference to which will be assigned to emp1.
Then you have:
> this.Name = 'jo';
The value of this is set when entering an execution context. For global code, it always references the global object (which is equivalent to window in a browser). So the above line creates a Name property of the global object and assigns the value 'jo';
What you wanted is probably:
emp1.setName('jo','555-5551');
The name of that method seems inappropriate given that it sets both the name and phone number.
> document.write(Employee.name Employee.phone);
Since you added the properties to the instance (emp1), likely that's the properties you want to read:
document.write(emp1.name + ' ' + emp1.phone);
or to use the getName method:
document.write(emp1.getName() + ' ' + emp1.phone);
and so on.
There's a lot wrong with your code example. The constructor is misspelled. The employee instances should be created like:
var emp1 = new Employee();
The instance properties should be set like:
emp1.setName('John');
You've also combined two setters into one, which is confusing.
To access the instance properties, you should use:
emp1.getName();
Not:
Employee.Name
Yes you have a lot of errors I think this is basically what you want to achieve.
function Employee(){
this.name;
this.phone;
this.getName = function(){
return this.name;
};
this.setName = function(name, phone){
this.name = name;
this.phone = phone;
};
}
function employ(){
var emp1 = new Employee();
emp1.name = 'jo';
emp1.phone = ' 555-5551' ;
alert(emp1.getName());
}
http://jsfiddle.net/umNTs/

Categories