I have recently started to learn JavaScript and would like to know if it is possible to use a object variable in a function directly within the same object. Here is my code so far.
var user = {
name: 'Example',
age: 687,
address: {
firstLine: '20',
secondLine: 'St Fake',
thirdLine: 'Fakeland'
},
logName: function(inputName, inputAge){
console.log(user.name);
console.log(user.age);
console.log(inputAge);
console.log(inputName);
}
};
user.logName('Richard', 20);
How is it possible to link to the name and age variables of user in the function without needing to prefix the object name onto the variable?
In most cases, you can just use the this keyword to get the object on which your function was called as a method upon. In your example:
var user = {
name: 'Example',
age: 687,
address: {
firstLine: '20',
secondLine: 'St Fake',
thirdLine: 'Fakeland'
},
logName: function(inputName, inputAge) {
console.log(this.name);
// ^^^^
console.log(this.age);
// ^^^^
console.log(inputAge);
console.log(inputName);
}
};
user.logName('Richard', 20); // method call on `user`,
// so `this` will become the `user` in the function
Welcome to the "this" key word!
Just reference it by this.value
You can use the this keyword . You can better understand this keyword using this article
The code will be like this
var user = {
name: 'Example',
age: 687,
address: {
firstLine: '20',
secondLine: 'St Fake',
thirdLine: 'Fakeland'
},
logName: function (inputName, inputAge) {
console.log(this.name);
console.log(this.age);
console.log(inputAge);
console.log(inputName);
}
};
user.logName('Richard', 20);
Related
Following code outputs {name: "Bob", surname: "Smith"} and it works fine. I want to know can I make it shorter.
((person = { name: 'Bob', surname: 'Smith', age: 22, }) => {
const {
name, // (a) create variable from deconstructing
surname,
} = person;
return {
name, // (b) reuse variable as new object parameter name (and value)
surname
}
})();
Can I somehow merge object deconstruction to variables (a) with returning a new object with Object Property Value shorthand (b)?
I use here shorthand but then its purpose is defeated by the need to manually re-use parameters. I want to mention the name or surname word in my function once not twice...
Destructure person in the function's declaration:
const result = (({ name, surname } = { name: 'Bob', surname: 'Smith', age: 22, }) => ({
name, // (b) reuse variable as new object parameter name (and value)
surname
}))();
console.log(result);
You can not mention it at all
((person = { name: 'Bob', surname: 'Smith', age: 22, }) => {
const {age,...ans} = person;
return ans
})()
Want where I use the arrow function so it returns 'correct'.
let mama2 = {
children:12,
surname: true,
town: 'umuadi',
school:'imo state university',
mamaChild:() => {
if (this.surname){
return 'correct'
}else{
return 'failed'
}
}
}
let mama3 = {
children:12,
surname: true,
town: 'umuadi',
school:'imo state university',
mamaChild:function() {
if (this.surname){
return 'correct'
}else{
return 'failed'
}
}
}
I want to know the difference between this two codes why it gives me a different result.
when I run this code on my console the first code gives me the result of 'failed' and the second gives me the result of 'correct'.
When you use this inside arrow function it refers to window object.
When you use this inside a normal function it refers to current object.
You can console log this in both cases to see the difference.
let mama2 = {
children: 12,
surname: true,
town: 'umuadi',
school: 'imo state university',
mamaChild: () => {
console.log(this); // window object
if (this.surname) {
return 'correct'
} else {
return 'failed'
}
}
}
mama2.mamaChild();
let mama3 = {
children: 12,
surname: true,
town: 'umuadi',
school: 'imo state university',
mamaChild: function () {
console.log(this); // mama3 object
if (this.surname) {
return 'correct'
} else {
return 'failed'
}
}
}
mama3.mamaChild();
Arrow functions bind the context of this to the outer scope, which in this case is not the object you are trying to reference. When you use a plain function(), this refers to the object with the value you are checking for.
Is there any downside to using named arguments for functions in JavaScript and PHP. I don't see any downside. There's the fact that you need to extract them (though you don't absolutely have to I guess) - but you can use that as a way of using defaults. Eg.
Javascript:
function myFunction (opt)
{
var name = opt.name || 'Barry',
age = opt.age || 26,
eyes = opt.eyes || 'brown';
}
And call it like this:
myFunction ({
name: 'Fred',
age: 56,
eyes: 'pink'
})
PHP
function myFunction ($opt)
{
$name = $opt['name'] ? $opt['name'] : 'Barry';
$age = $opt['age'] ? $opt['age'] : 26;
$eyes = $opt['eyes'] ? $opt['eyes'] : 'brown';
}
EDIT: Maybe use the extract() function here to make things easier.
And call it like this:
myFunction ([
'name' => 'Fred',
'age' => 56,
'eyes' => 'pink'
])
In Javascript, you could use default values, like
function myFunction({ name = 'Barry', age = 26, eyes = 'brown'} = {}) {
console.log(name, age, eyes);
}
myFunction();
myFunction({ name: undefined, age: 30 });
myFunction({ name: 'jane', age: 35, eyes: 'blue' });
Is there any downside to using named arguments for functions in JavaScript and PHP
Just one. Neither PHP nor JavaScript support named arguments.
EDIT
Here wiki page on what named arguments really is, as many seem to get the concept wrong.
You are talking about an options object, not named arguments. Named arguments are not available in JavaScript, and would look something like this following line. Note that the parameters are not inside an object:
myFunction( name: 'Fred', age: 56, eyes: 'pink' );
Using an options object rather than individual function parameters is useful if there are more than a few arguments to pass. The object doesn't have to worry about ordering, or whether elements are optional.
ES2015 supports destructuring and defaults, which can simplify this even more, though the formatting may look very different at first...
function myFunction ({ name = 'Barry', age = 26, eyes = 'brown'})
{
console.log(name, age, eyes);
}
This function will throw an error if an object is not passed, but it can accept an empty object, or one with any number of those keys. As Nina's answer shows, you would need another default to prevent that error:
function myFunction ({ name = 'Barry', age = 26, eyes = 'brown'} = {})
{
console.log(name, age, eyes);
}
I have a JavaScript array of objects. Something like this:
var people = [
{ id:1, firstName: 'Joe', lastName: 'Smith' },
{ id:2, firstName: 'Bill', lastName: 'Smith' }
];
I am iterating through the people using forEach. Here is my code:
function doSomething() {
people.forEach(function(person, self) {
self.helpPerson(person);
}, this);
}
function helpPerson(person) {
alert('Welcome ' + person.firstName);
}
I am trying to call helpPerson from within the forEach loop. However, when I attempt to call it, I get an error that says:
TypeError: self.helpPerson is not a function
If I add console.log(self);, "0" gets printed to the console window. This implies that I'm not passing in my parameter correctly. Or, I'm misunderstanding closures (just when I thought I fully understood it :)).
So, why doesn't self exit?
You don't need to invoke helpPerson with a this, self, or any other context. Just invoke it directly:
var people = [
{ id:1, firstName: 'Joe', lastName: 'Smith' },
{ id:2, firstName: 'Bill', lastName: 'Smith' }
];
function doSomething() {
people.forEach(function(person) {
helpPerson(person);
});
}
function helpPerson(person) {
alert('Welcome ' + person.firstName);
}
When you log self to the console you are seeing "0" because it is printing the index of the loop iteration.
See the documentation for forEach to see what callbacks are passed to it's forEach function.
Typically, self is used to capture a context in a closure (var self = this;). Please see the related links to this question because that is a very important concept.
helpPerson is a global variable, not a property of the array.
self.helpPerson(person); should be helpPerson(person);
forEach passes two arguments to the callback: the item being iterated and its index. That's why console is logging 0.
You are expecting this to pass as an argument, when it's actually more magical than that. You can use this inside the callback and it will use the context of whatever this you passed as an argument to the forEach
function doSomething() {
people.forEach(function(person, index) {
this.helpPerson(person); //Or for brevity, you can just remove `this` here
}, this);
}
function helpPerson(person) {
alert('Welcome ' + person.firstName);
}
forEach takes 2 parameters : a function(val, index, arr) and a this binding argument .
people.forEach(function(person, self) {
self.helpPerson(person); // self here would be array index number
}, this);
the way you've defined helpPerson() you can call it directly like helpPerson(person);
Please see comments
var people = [
{ id:1, firstName: 'Joe', lastName: 'Smith' },
{ id:2, firstName: 'Bill', lastName: 'Smith' }
];
function doSomething() {
people.forEach(function(person) { // no parameter for index required
helpPerson(person); // just call the function
}); // no other parameter is required
}
function helpPerson(person) {
alert('Welcome ' + person.firstName);
}
doSomething();
I'm writing an app in node and I am running into something strange.
I pass an object into a function with the call() method to modify that object. When inside the function when I do console.log(this) it returns the object fine, however when I try to do console.log(this.foo) or try to modify the object it says undefined. UPDATE: I also have to mention I pass this function in an object because I have to inject the functions in to another function. (more specific, I'm trying to get this to work. Maybe that is also part of the problem.
var obj = {name: "John", age: 23};
var functions = {up: function() { /* do stuff */ }, down: function() { /* do stuff */
functions.up.call(obj);
up: function() {
console.log(this); //returns {name: "John", age: 23}
console.log(this.name); //returns undefined
this.wife = "Jenny"; //doesn't do anything
}
However if I set properties with an '_' they do exist but don't show up when I call console.log(this);
up: function() {
this._wife = "Jenny"; //doesn't do anything
console.log(this._wife); //returns "Jenny"
console.log(this); //still returns {name: "John", age: 23}
}
I've tried everything like using this.set(key, value), this.get(key), this.attributes["name"].value,..
Maybe I'm misunderstanding how 'this' works, but after hours of searching and trying things I'm clueless..
When trying your code in the console I fixed the syntax to a function expression and it works for me, perhaps this was your problem?
var obj = {name: "John", age: 23};
up.call(obj);
function up() {
console.log(this); //returns {name: "John", age: 23}
console.log(this.name); //returns "John"
this.wife = "Jenny"; // works
console.log(this);
}
I'm getting working output from this in node, chrome/win7 & notepad++ plugin :
var obj = { name: "John", age: 23 };
var functions = {
up: function() {
console.log(this); //returns {name: "John", age: 23}
console.log(this.name); //returns undefined
this.wife = "Jenny"; }, //doesn't do anything
down: function(){ } }
functions.up.call(obj);
console.log('obj:',obj);
output :
{ name: 'John', age: 23 }
John
obj: { name: 'John', age: 23, wife: 'Jenny' }
Your understanding of 'this' seems correct
you could try replacing
functions.up.call(obj);
with
temp = obj.up;
obj.up = functions.up;
obj.up();
obj.up = temp;//or: delete obj.up;
I had the same problem. Finally I found solution - I put the problematic code in round brackets:
var i = node.declarations.length; //Error: cannot get length of undefined
var i = (node.declarations).length; // 11
I guess you should do something like that:
console.log((this.name).toString());
or
console.log((this.name));