Why can't I access properties directly within this object? [duplicate] - javascript

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 3 years ago.
I have read the documentation for https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Why can't we directly access this.prop, but rather we have to write a function just to return this.prop?
var test = {
prop: 42,
func: function() {
return this.prop;
},
directAccess: this.prop
};
console.log(test.func());
// expected output: 42
console.log(test.directAccess);
// expected output: 42
// actual output: undefined

It's all about context, at the time you're constructing the object test , the this context is the parent scope which is creating the object.
When invoking the function, your scope is now that of test which at that point does have a property of prop.

You can directly access prop. However, the way to do that is to use test.prop.
In JavaScript, this is a special variable that is set to the "receiver" of a function call, meaning the object to the left of the dot. When you write
test.func()
then test is the receiver, so this points to test inside the function.
In the case of directAccess, there is no function. The expression this.prop is evaluated at the time test is defined. At this point, this is probably the JavaScript default object, which does not have a property called prop, so you get undefined.
You might be used to Java, in which this inside a class always refers to an instance of the class itself. It doesn't work that way in JavaScript.

Related

Why call function in window scope is different from object scope [duplicate]

This question already has answers here:
Using the variable "name" doesn't work with a JS object
(4 answers)
Closed 5 years ago.
Why calling Person in window scope is returning "[Object Object]" while call that in object scope is returning Object.
global window object already have a property of name, and it's inside the scope of native code.
https://www.w3schools.com/jsref/prop_win_name.asp
window.name is a getter/setter to set the name of the window. As such, it has to be of type string.
Try this:
window.name = ["something", "else"];
You will see that now window.name is set to "something,else"; which is the result of Array.toString().
This is exactly what is happening here. When you call an object's toString, you get [object Object].
Your program works fine if you do not use the predefined window.name getter/setter.
function Person(first, last) {
this.something = {
first,
last
};
}
f = {};
Person.call(f, "fsd", "fsd");
console.log(f.something);
g = window;
Person.call(g, "fsd", "fsd");
console.log(g.something);
More on getter/setters in javascript:
Setters: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/set
Getters: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/get

Lexical `this` and Timeout [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
Im reading through the YDKJS books and I thought I understood lexical this for the most part.
However there is a section with code that shows this:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome
Ok so the first obj.cool() makes sense of course....but why is the setTimeout printing not awesome.....I mean it's still calling obj.cool() which this refers to it's own objects id?
Or does setTimeout get called as another function that calls obj.cool()? but even in that case (Which I tried calling obj.cool() inside another function that also had an id property and it still printed the right one......so why would the this change with setTimeout?
Since the OBJ.COOL function is passed by reference, you are not actually passing the context object with it. The function gets new invocation context and executes on the WINDOW object, which now has a property called ID which was defined earlier.

Why "this" is not working? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
In java script when we make a new constructor function we use "this.property name". We use "this" to refer the object which currently in use. But in a general function we doesn't use "this" keyword. According to my understanding if we use "this" in function it should point to the current function. However when we used, it was not producing the expected result. Why? Example
function greet(name){ console.log("Hello " + this.name);
}
Output is "Hello" then blank.
Because in general function, we are by default referring 'window' object so anything we make it becomes window level object or variable.
Like,
function fun(){
this.title = "window";
}
fun();
or window.fun(); //both are same. Since we call window.fun, this.title means window.fun.
If you create like this:
var obj = {
}
**Now to make title at obj level, you can do like this:
fun.call(obj);
Now you can call obj.title.**
Read this about this
In most cases, the value of this is determined by how a function is called.
When you use the new keyword in javascript an implicit object is created and returned from the function call. Inside of the function this refers to the newly created object. Calling a function without new does not have the same behavior.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

Why does passing a JavaScript object's method not update the object? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I noticed that when passing an object's method (which updates one of the object's own properties) as an argument to another function, the original object will not be modified.
For example:
var obj = {
foo: 0,
bar: function () {
this.foo++;
}
};
function baz(callback) {
callback();
}
baz(obj.bar); // does not alter obj
obj.bar(); // increments obj.foo successfully
console.log(obj.foo); // should be 2, not 1
Why is this, since JavaScript objects are passed by reference?
This is because the context - or this value - of a function is based on how it's called, not on how it's defined. Your bar function doesn't know it's inside the obj object.
When you do obj.bar();, you are calling it in the context of obj, thus this is what you expect.
When you do baz(obj.bar);, you are passing the bar function as a parameter. It no longer has any ties to the obj object. Remember, functions can be treated like variables. So, when baz runs its callback, it's ran in the "global" context (this is window).
The solution here is to use .bind() to "lock in" the this value.
baz(obj.bar.bind(obj));
Because you need to bind the callback to a specific object.
baz(obj.bar.bind(obj));
Functions are only automatically bound to the object before . when you perform the call in the same expression. Simply accessing the property doesn't bind it.

Why does `this` refers to `o` here (o.method)() instead of a global object [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
Suppose I have an object:
var o = {
prop: 3,
method: function() {return this.prop}
}
I was expecting this
(o.method)()
to return undefined, however it returned 3 meaning that this is set to o inside method. Why is it so? If you evaluate (o.method) separately, it evaluates to a standalone function, so I expected this to reference global object. Why, for example, the difference exists here:
(o.method)() vs (o.method || true)()
I know that o.method() will use o as context, the question is specifically about accessing the function first like this (o.method) and then calling it.
That's just how JavaScript's rules work. Unless you do some contortions, this usually means the thing before the . when you access the method prior to calling it. In this case, that's o.
The following statements are identical:
(o.method)();
o.method();
o.method.call(o);
o["method"]();
However, if you put the method on something else, it'll take on the meaning of the thing it's on:
var p = {prop: 42, method: o.method};
p.method(); // returns 42
var method = o.method;
var prop = 13;
method(); // returns 13
Note: As JavaScript grew to be much more than it was originally designed for, people realized that this probably wasn't the most intuitive way for this to work, so in ES6 if you use "Arrow Functions" (aka Lambda Functions) it won't rebind this.

Categories