What difference between This and That [duplicate] - javascript

This question already has answers here:
What does 'var that = this;' mean in JavaScript?
(6 answers)
Closed 8 years ago.
I'd like to know and understand the different between this and that, and when I have to use it.
I ready many post and many tutorial but I don't understand yet
this is my class
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
console.log(this.member); // foo
console.log(that.member); // foo
return dec() ? that.member : null;
};
}
New
var myContainer = new Container('foo');
myContainer.service()
Calling myContainer.service() will return 'abc' the first three times it is called.
After that, it will return null
Why i have to do var that = this ??

this is a variable that gets the context of the current function (which depends on how it was called).
that has no special meaning. It is just a variable to which a value has been assigned.
In this particular case, that is assigned the value that this has while the Container is running, and is used inside the service function (but still has the value that is the context of the call to Container. Since service is a different function, its value of this could be different.
Normally, for this particular design of function, Container would be called as a constructor function (so this would be the instance object of Container) and then service would be called in the context of that instance object so you could use this instead of passing the value around via that. I have no idea why the author of that code chose to use that here.

Related

Javascript cannot set property from a method invoked using this [duplicate]

This question already has answers here:
Javascript lost context when assigned to other variable
(4 answers)
Closed 4 years ago.
In the following Javascript code, the first call to saveResult from writeData succeeds while the second doesn't, please help.
class SimpleClass {
constructor() {
this.ir = "";
}
saveResult(res) {
console.log("entered save result")
this.ir = res;
console.log("value saved is " + this.ir);
console.log("end save result");
}
writeData() {
this.saveResult("abc"); //works fine
var sr = this.saveResult;
sr("abc"); //throws error -> Cannot set property 'ir' of undefined
}
} //end of class
function testLocally() {
var sc = new SimpleClass();
var wr = sc.writeData();
console.log("done");
}
testLocally();
A function gets is context based on how it is invoked. When you call it like
this.saveResult("abc"), this inside the function will refer to the this which called it, which in your case is the class context since you created an instance of class and invoked writeData method from the class instance causing the this inside writeData to refer to class context.
However when you run it like this:
var sr = this.saveResult;
sr("abc");
Although sr has the reference to the function, its called from the window context and hence it doesn't work correctly. You can call it using .call method and provide the context like this:
var sr = this.saveResult;
sr.call(this, "abc");

Referring to Class instantiater in javascript [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I have this method of a JavaScript class that I've created:
resetRule() {
let sheetRules = Array.from(this.sheet.rules);
sheetRules.forEach(function(node, i) {
if(node.name != undefined) {
newRule.sheet.deleteRule(i);
}
});
}
when you instantiate a class, it essentially has to be set to a variable, like so:
const newRule = new NewRule(*params*);
and the methods/properties of said class can refer to the class object using this. like so:
this.method();
this.property;
What I'd like to know is: how does one refer back to the variable that instantiated the class within a function that is called by a method of said class?
To be even clearer: a function that is called within a method of a class alters the scope, which also means it alters the definition of this.. My question is: how do you get around this? How could you access the variable that instantiated the class when you are out the of scope of the methods within said class?
As I was composing this question, I realized that you can set the this value for a .forEach loop like this:
resetRule() {
let sheetRules = Array.from(this.sheet.rules);
sheetRules.forEach(function(node, i) {
if(node.name != undefined) {
this.sheet.deleteRule(i);
}
}, this);
}
However, the way this code works is something that--as far as I know--is just a benefit of the .forEach method, and I'd still like to know how it should be handled in general.
Hopefully this should help you out, using your example.
class Rule {
constructor(rules) {
this.sheet = {
rules: rules || []
}
}
log(){
console.log('rules:',this.sheet.rules)
}
resetRule() {
let sheetRules = Array.from(this.sheet.rules);
let self = this; // <-- here you can capture the instance
sheetRules.forEach(function(node, i) {
self.log() // <-- here you can use it in forEach
if (node.name != undefined)
this.sheet.deleteRule(i);
});
}
}
const fooRule = new Rule(['foo'])
const barRule = new Rule(['bar'])
fooRule.resetRule()
barRule.resetRule()
fooRule.log()
barRule.log()
Your forEach works because as you discovered, you passed this as an argument for the thisArg parameter. However, if you didn't, you could have just as easily set it to a variable in the outer scope and used it in the block scope.
Generally creating a variable called self or that and setting it to this is helpful, especially for arrow functions, which set this to the encapsulating scope and not the instance object.
You could make a temporary variable called self or something which would allow you to use both the object containing "this" instance as well as within that anonymous function passed to forEach, this which will refer to sheetRules when you don't specify another variable to use as this
resetRule() {
let sheetRules = Array.from(this.sheet.rules);
let self = this;
sheetRules.forEach(function(node, i) {
if(node.name != undefined) {
self.sheet.deleteRule(i);
}
});
}
If I've not misunderstood you're looking for a way to retain your scope? You have a few options here.
The immediate answers would be to use Function.prototype.bind() or Function.prototype.call() to specify the context of this when invoking those methods.
Alternatively you could just make the scope of your this available where needed:
var MyClass = function () {
// Here we bind the local scope to a variable that will give us context where necessary.
// While it's not needed here, it can give context and set a pattern of reability through repitition.
var vm = this;
vm.methodA = function () {
// We continue to set our 'vm' pointer variable when needed.
var vm = this;
globalMethod.then(function () {
// We're able to retain context of our `this` through having scope of our 'vm' variable.
vm.methodB();
});
};
vm.methodB = function () {
console.log('I did stuff!');
};
};

How do I find the meaning of 'This' in following Javascript Code? [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.
What does this.radioStation refer to in the following code: does 'this.radiostaion' refer to Car or the function chagestation. Your input/ clarification would be appreciated. Any good rule of thumb to clear this up?
var Car = function () {
var gasolineLevel = 10;
function useGas (amt) {
if(gasolineLevel - amt < 0) {
console.log("out of gas :[");
} else {
gasolineLevel -= amt;
}
};
return {
radioStation: "104.5",
changeStation: function (station) {
this.radioStation = station;
},
go: function (speed) { useGas(speed); }
};
};
var Ferrari = Car();
console.log(Ferrari);
console.log(Ferrari.go(2));
console.log(Ferrari.go(10));
In changeStation, this will be whatever it was set to when calling changeStation. In normal functions, this is effectively a hidden argument that's determined by how the function is called.
In that specific example, you never call changeStation, so we can't tell you what this will be if/when you do.
If you called it like this:
var ferrari = Car();
ferrari.changeStation();
...then this would refer to the object created by Car (the one referenced by ferrari, created by the object initializer returned by Car at the end), because we called changeStation as part of a property accessor operation on ferrari.
But if you called it like this:
var ferrari = Car();
var changeStation = ferrari.changeStation;
changeStation();
then this would refer to the global object (in loose mode) or would be undefined (in strict mode).

What does "let _self = this" mean in Javascript/Typescript? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
What underlies this JavaScript idiom: var self = this?
(10 answers)
Closed 5 months ago.
In this code snippet, why is it that this.identifier doesn't work but _self.url works?
getConfig() {
let _self = this;
return function () {
this.page.url = this.url || window.location.href;
this.page.identifier = _self.identifier;
this.page.category_id = this.categoryId;
this.language = this.lang;
};
}
So does let _self = this actually do?
Functions have something called a context. A context is the object the function is being called on.
let person = {
name:"bill",
speak:function(){
console.log("hi i am "+this.name)
}
}
if you were to do person.speak()
it will be called on the object that was defined. The variable person is the context
so when you say this. it's the same as saying person.name
Now you can attach the function to something else.
var newperson = {name:'jill'}
newperson.speak = person.speak;
this will print hi i am jill when it's called.
Now on to step two.
GetConfig returns a function, however this function is not attached any object.
Check this out.
let person = {
name:"bill",
getSpeakFunction:function(){
return function(){
console.log('hi my name is '+this.name)
}
}
}
let func = person.getSpeakFunction()
Now the function func is all by himself.
Now when it is called who is this who the hell are you talking about.
That is what the function is thinking.
So we can help the function out by saying.
let person = {
name:"bill",
getSpeakFunction:function(){
let context = this; //listen hear function this is what i am talking about
return function(){
console.log('hi my name is '+context.name)
}
}
}
let func = person.getSpeakFunction()
this is special the language decides the value of this, however context is not. Context will be whatever is assigned to it. It will not change unless you the programmer changes it.
so using the word _self, context, $this
or anything else when you assign the value of this to it.
it is 'locked in place' like any other regular variable.
let a = 2;
//this will never change
let _self = this //_self will never change as it's your variable
Now when you call your function and it looks for _self. It knows exactly what you are talking about.
It takes the value of this (which is determined by how the function is called) and stores it in a variable (which is still accessible in the closure (that will have a different value of this when it is called) that getConfig is returning).

What is happening when using the keyword this in lambdas vs functions with Typescript [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I am using Typescript for an Angular 2 project. I notice that when we use the keyword this inside a labmda expression vs a function, this refers to different things.
For example, let's say I have an Angular component like the following.
export class MyComponet {
isActive = true;
names = [ "john", "jeff", "jared" ];
doSomethingWithLambda() {
names.forEach( (value, index) => {
if(this.isActive) { //this.isActive refers to MyComponent.isActive
//do something...
}
});
}
doSomethingWithFunction() {
names.forEach( function(value, index) {
if(this.isActive) { //this.isActive is undefined, since this refers to the function
//do something
}
});
}
doSomethingWithFunction2() {
let isActive = this.isActive;
names.forEach( function(value, index) {
if(isActive) { //if we change isActive will this also change MyComponent.isActive?
//do something
}
});
}
}
What is really happening here (behind the scene, so to speak)? What's the magic behind this inside a lambda that makes it able to "correctly" refer to the outer class' fields? I understand this inside a function will refer to the function itself.
Also, I have a doSomethingWithFunction2 method that will reference MyComponent.isActive into a local variable. If I change that local variable, that should be like changing the one it references, right? (regardless of it being a "primitive" like integer/number or an "object" like JSON { })
The fat-arrow function syntax is shorthand for:
function () { }.bind(this);
bind is a Javascript ES5 method equivalent to this:
Function.prototype.bind = function bind(context) {
var func = this;
return function () {
return func.apply(context, arguments);
};
}
In regards to
Also, I have a doSomethingWithFunction2 method that will reference MyComponent.isActive into a local variable. If I change that local variable, that should be like changing the one it references, right? (regardless of it being a "primitive" like integer/number or an "object" like JSON { })
In Javascript, variables are like pointers and except for some limited cases (primitives and copy-on-write objects) will change the referenced value when mutated. Reassigning will not change the original value, e.g. isActive = false; but this.isActive = false would in fact re-assign the variable isActive on this which is now hopefully correctly assigned.
This has to do with how lambda function are implement in TS. this in arrow function is lexically inferred so it more in line with below code
function Person() {
var self = this; // Some choose that instead of self.
// Choose one and be consistent.
self.age = 0;
setInterval(function growUp() {
// The callback refers to the self variable of which
// the value is the expected object.
self.age++;
}, 1000);
}
So inside the lambda function it is not actually this but a context closer self. This may not be actual implementation but much closer to give you understanding of what is happening.
Now when you are outside the my impotent this refers to global var which would be window
The lambda function is similar to javascripts bind function.
Protip see your transpiled JS how your lambda function is transforming.

Categories

Resources