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));
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
})()
function a() {
console.log(5);
return;
}
var x = a;
x();
// Line 2 Output: 5 // compiler output read function a ()
// Line 6 Output: undefined // result of execution x ()
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first);
}
};
Output: 'john'
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first);
}
};
person.first = 'pedro';
person.full()
// Line 5 Output: 'pedro'
// Line 9 Output: undefined // result of execution x ()
Does anyone explain to me what's happening? Because Output is not:
'john' -> here gives 'pedro' by the seen, the person.first statement executes first that the console.log (this.first)
'pedro' -> here gives undefined, it's the same case as above
Your question worded strangely, but I will try to answer as best as I can.
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first);
}
};
When a function is defined without a return, undefined will always be returned back to the caller. JavaScript functions always return something.
You would have to state a return if you wanted to use that variable from the function.
You can grab the object's variables through namespacing, in your example, you could do: person.first, person.last.
And if you wanted the function to return something, you would declare person like so:
var person = {
first: 'John',
last: 'Smith',
full: function() {
return this.first + " " + this.last;
}
};
I'm trying to figure out the most terse way to return an array of objects from a ts function. The following function works as expected:
getAuthors1(): Author[]
{
var authors: Author[] =
[
{
FirstName: "John";
MI: "J";
LastName: "Smith";
}
];
return authors;
}
The following function errors out b/c it appears that ts won't let me return an object array directly as opposed to as a variable:
getAuthors2(): Author[]
{
return Author[] =
[
{
FirstName: "John";
MI: "J";
LastName: "Smith";
}
];
}
The following function errors out b/c a value isn't provided for MI:
getAuthors3(): Author[]
{
var authors: Author[] =
[
{
FirstName: "John";
LastName: "Smith";
}
];
return authors;
}
Questions:
Are values required for all object properties when creating an object initialized array?
1a. If this is the case do developers typically initialize property values in the class?
Is there a way to return an object array directly, similar to my getAuthors2() example above, as opposed to having to assign this to a variable and then return the variable?
If you have an interface defined and you create an object where you tell TypeScript that it should be of that type, it will complain for any missing property, as it should.
One way to get around this is to use a mapped type where you state that each property of the object is optional, and use it like Partial< Author >. See the official documentation for more info.
You can return the array right away, just remove the type that you've added after return:
getAuthors2(): Author[] {
return [
{
FirstName: 'John',
MI: 'J',
LastName: 'Smith',
}
];
}
Also wherever possible you should remove the manually defined types, like the return Author[] from your functions. TypeScript will use type inference to figure it out by itself.
In your specific example either you leave the return type defined, and typescript will make the required checks or use something similar to what you have in getAuthors3. If you get or have the objects already typed just place them in the array and TypeScript will do the rest:
getAuthors() {
const author: Author = {
FirstName: 'John',
MI: 'J',
LastName: 'Smith',
};
return [author];
}
Return the array, not the result of an array assignment.
function getAuthors() {
return [{
FirstName: "John",
MI: "J",
LastName: "Smith"
}];
}
console.log(getAuthors());
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);
I found out that there is no way to do this. However, thanks everyone!
In javascript, can I override the brackets to access characters in a string?
I have something like this:
function f() {
var list = [{name: 'test'}, {name: 'test2'}];
}
And I would like to get properties from that list that's inside the function, I think there is some method that overrides default [], but I really don't know what to look for.
f[0] // {name: 'test'}
f['test2'] // {name: 'test2'}
Your list variable will be private to f() unless you do one of two things.
First, you could try returning list from f() so that you can then get to the properties you need.
function f() {
var list = [{name: 'test'}, {name: 'test2'}];
return list;
}
var f = f();
f[0] // {name: 'test'};
f['test'] // will return undefined; we'll come back to this
Second, and I think this option is probably what you're looking for as you tagged the question with 'oop', you could make f() a constructor:
function f() {
this.list = [{name: 'test'}, {name: 'test2'}];
}
var f1 = new f();
f1['list'][0] // {name: 'test'};
f1.list[0] // will also return {name: 'test'};
f1.list['test'] // still will return undefined...
...
The reason you will not be able to access a value using ['test'] or ['test2'] is because they are your values, whereas ordinarily the values are what we want to access in an object using the key (in this case ['name'] or .name). So what you might want is something like this:
f1.list[0].name // will return 'test'
f1.list[1].name // will return 'test2'
Hope this clears up the confusion.
Just use an object instead of an array:
var byname = {
"test": {name: 'test'},
"test2": {name: 'test2'}
};
// bracket notation:
byname["test2"] // {name: 'test2'}
// dot notation:
byname.test // {name: 'test'}
Since you said that you never will access the structure by index, it will be OK to use the unordered key-value-map structure. To save typing, you could create that object dynamically from your array as well:
var list = [{name: 'test'}, {name: 'test2'}];
var byname = {};
for (var i=0; i<list.length; i++)
byname[list[i].name] = list[i];