what is the meaning of this? setTimeOut(() => this.active=true, 0) - javascript

I am practicing angularjs2 and I notice this sentence but cannot understand what this means.
#Component({
selector: 'hero-form',
templateUrl: 'app/hero-form.component.html'
})
export class HeroFormComponent {
model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');
active = true;
newHero() {
this.model = new Hero(42, '', '');
this.active = false;
setTimeOut(()=> this.active=true, 0)*
}
}
I know in JavaScript there is a function name setTimeOut but cannot understand the () and arrow =>...
Thanks in advance!

This is the new JavaScript arrow function notation. The line you quoted is almost equivalent to this piece of code in the traditional function notation:
setTimeout(function() {
this.active = true;
}, 0);
However in the traditional notation, this will be bound to the global object (outside of strict mode - in strict mode, you will get a ReferenceError), due to how binding of this in execution contexts works. The traditional workaround before the introduction of arrow functions would be:
var self = this;
setTimeout(function() {
self.active = true;
}, 0)
Arrow functions solve this problem by lexically binding this, just as any other variable, instead of defining their own. In addition to how this is treated, arrow functions do not implicitly define their own arguments or super variables either, but bind them lexically.
Digging deeper, what does newHero() do? It is a constructor function. When you call it, a new object is allocated, and it can be referred to within the function body by the variable this. The constructor sets two properties on the this object; these properties are .model and .active, being given specific values.
The expression (() => this.active = true) creates a function object. It describes what should execute at a later time. When the function object is called, the body gets executed. So the line of code creates the function object and gives it to setTimeout(), which will call the function object after the given length of time - in this case, 0 milliseconds.

Related

Classes and methods javascript [duplicate]

Below I am creating an object in JavaScript. Within the constructor I am setting up an event listener. The problem is that when the event gets fired, this.prop cannot be found, and undefined prints out. How do I solve this?
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
When the event handler gets called, "this" no longer references the "someObj" object. You need to capture "this" into a local variable that the mouseMoving function will capture.
var someObj = function someObj(){
this.prop = 33;
var self = this;
this.mouseMoving = function() { console.log(self.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
I'm assuming "someObj is a constructor, i.e. intended to be called with as new someObj(), otherwise "this" will be the global scope.
The "this" keyword can be confusing in JavaScript, because it doesn't work the same way as in other languages. The key thing to remember is that it is bound to the calling object when the function is called, not when the function is created.
The javascript built-in Function.prototype.bind() is intended for this purpose.
For example:
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);
}
More on the bind method here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Other wise you have to pass a reference of the object someObj to the element and use that reference in the line:
console.log(this.referenceToObject.prop); //this references the DOM element in an event.
From Section 4.3 of JavaScript: The Good Parts by Douglas Crockford:
Invoking a function suspends the
execution of the current function,
passing control and parameters to the
new function. In addition to the
declared parameters, every function
receives two additional parameters:
this and arguments. The this parameter
is very important in object oriented
programming, and its value is
determined by the invocation pattern.
There are four patterns of invocation
in JavaScript: the method invocation
pattern, the function invocation
pattern, the constructor invocation
pattern, and the apply invocation
pattern. The patterns differ in how
the bonus parameter this is
initialized.
Crockford continues to explains the binding of 'this' in each of these patterns, as follows:
The Method Invocation Pattern:
When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object.
The Function Invocation Pattern:
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language.
The Constructor Invocation Pattern:
If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function's prototype member, and this will be bound to that new object.
The Apply Invocation Pattern:
The apply method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value of this. The apply method takes two parameters. The first is the value that should be bound to this. The second is an array of parameters.
You could use a variable named 'me', to avoid conflict with the global JavaScript variable 'self':
function someObj() {
var me = this;
this.prop = 33;
this.mouseMoving = function() {
alert(me.prop);
}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
First, you need to understand how 'this' works in JavaScript. 'this' keyword doesn't behave how it behaves in other languages like C# or Java. Read following post to understand more,
What is the rationale for the behavior of the 'this' keyword in JavaScript?
Once you understand that, as Matthew outlined in his code, you can save reference to 'this' and use that reference inside the mouseMoving function.
Though overall, I will advise that you use a JavaScript framework (e.g. jQuery, YUI, MooTools) which will take care of these issues for you. E.g. In Internet Explorer, you use addEvent to attach event and not addEventListenr.
You have some typos on your function declaration.
Your prop variable is also defined as a "public" or "visible" member (by using this.prop), doing so forces you to store the reference of this from the outer function (that is actually a reference to the object instance), as a "private" member of the function (using var) to get access the instance of the created object and read the "public" prop member.
You have some alternatives to rewrite this code:
function someObj (){
var self = this;
this.prop = 33;
this.mouseMoving = function() { alert(self.prop);} // You access the current
// instance, stored in *self*
// since *this*, inside the
// function, is in another
// context.
//...
}
var mySomeObj = new someObj(); // Object instantiation
Or you could:
function someObj (){
var prop = 33;
this.mouseMoving = function() { alert(prop);}
//...
}
var mySomeObj = new someObj(); // Object instantiation
The variables declared with var, are accesible to the functions declared inside of the major constructor function, this feature is known as Closures.

Am I misunderstanding the use of `this` in React or even in Javascript?

There are already several questions on this topic, and I've looked at all I've found - my question is in order to clear up for myself some (apparent) contradictions that I'm seeing. I suspect there is a better solution than the only one I have working right now. I'm pretty new to Javascript.
I've read through the scoping rules on this as described by e.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this . My understanding from reading is that although a lot depends on calling context, if a function is a method of an object then within the function this will be the object itself. I thought this rule trumped the other rules, but perhaps I have misunderstood.
I've also read a post at https://medium.com/byte-sized-react/what-is-this-in-react-25c62c31480 which essentially says that if I want to access object state in a method via this, and I have code like
class App extends Component {
constructor(props) {
super(props);
}
clickFunction() {
console.log(this.props.value);
}
render() {
return(
<div onClick={this.clickFunction}>Click Me!</div>
);
}
}
then I need to explicitly bind the object to clickFunction() by either adding a line to the constructor like
this.clickFunction = this.clickFunction.bind(this);
or by using arrow notation to define clickFunction(), like
const clickFunction = () => { ... }
The first of these solutions works for me - I have not got the second working. It seems strange to me that I need to use either solution since (a) it seems to contradict what I thought was the assertion in the docs that an object method will treat the object as this, and (b) I don't see people doing this sort of thing in other tutorial examples that I look at.
For instance, there is a React tutorial at https://reactjs.org/tutorial/tutorial.html which defines object methods like renderSquare(i) and does not at any point explicitly bind these methods to the object.
If I try to do something which seems to me completely analogous to that tutorial, and don't explicitly add lines to the constructor to bind each method to the object, i.e. lines like this.clickFunction = this.clickFunction.bind(this), then I can't get my code to work.
Can anyone explain to me what I am misunderstanding about the tutorial and the documentation - why does the tutorial work even though there is no explicit binding to the object? The only difference I can spot between it and my own code is that I have use strict. Is there a better fix than the this.clickFunction.bind(this) solution I'm currently using? Adding one extra line of code to the constructor per method, to explicitly bind all my methods, seems pretty clunky.
Arrow functions binds your functions to your class directly. But when if you use
const clickFunction = () => { ... }
This will create a inner function, and does not bind it to the class.
You can use
clickFunction = () => { ... }
which will do similar to
this.clickFunction = this.clickFunction.bind(this);
You're right that, when calling a function from an object, the this keyword ends up being that object. So running something like:
const app = new App();
app.clickFunction();
Would yield the result you're expecting, because it's being called directly from the App class.
However, when you use that function as an event handler in your JSX, you're passing a reference to that function as a callback. By default, the function's this keyword is not determined until you call it, so it will be assigned based on the lexical context it's called from. You could imagine, when you set the handler, something like the following is happening under the hood:
const callback = app.clickFunction;
// click event happens
callback(event);
Here you can see that the call to callback() is just a bare function call. There's no app. prefixing it to provide the lexical context for this.
The two ways around this behavior, which you've already listed, explicitly set the this keyword to the object they originally live on. Calling this.clickFunction = this.clickFunction.bind(this) is the most explicit in that it takes a normal function and manually binds this to the value of this during object construction. Which will be the object being constructed.
Arrow functions do the same thing, but without the explicit binding. This is actually a functional difference between arrow functions and regular functions that a lot of people gloss over since they're typically chosen for stylistic or brevity purposes. Arguably, arrow functions behave as most programmers would expect, while normal functions behave in a way that's pretty unique to Javascript (and therefore pretty confusing).
Second arrow method, it will take this reference where the method is defined not from where it is called. so it will take this reference of class.
Ref. this in arrow function
You have valid points
Why tutorial worked? If you see renderSquare implementation you will notice that it is not using this in its implementation so it does not have to bind itself with this. Your implementation might not working because you may be using this inside method implementation.
renderSquare(i) {
return <Square value={i} />;
}
When you get references like this.clickFunction, you are only getting reference of that particular function which is not bind to any object, which is why calling it will fail if you try to refer variables using this
See this fiddle https://jsfiddle.net/yh3jw5nk/1/ for more explaination
This is determined at runtime and depending on the code, it can be something different.
this is
determined at runtime, when a function is envoked
determined by how a function is invoked, not where the function is
defined
a reference to an object.
will always be an object
global (this) not available in strict mode
Example 1: this = window
var name = 'Global';
var callName1 = function() {
var name = 'Peter';
console.log('--- From callName1 ----');
console.log(this.name);
//console.log(this);
callName2();
}
var callName2 = function() {
var name = 'Jane';
console.log('--- From callName2 ----');
console.log(this.name);
//console.log(this);
}
callName1();
var execute = function(fn) {
var name = 'Mary';
console.log('--- From execute ----');
console.log(this.name);
//console.log(this);
}
execute(callName2);
Example 2: not available in strict mode
'use strict';
var name = 'Global';
var callName1 = function() {
var name = 'Peter';
console.log('--- From callName1 ----');
console.log(this.name);
console.log(this);
}
callName1();
Example 3: examining this with method invocation
var name = 'global';
var obj = {
name: 'James Obj1',
func: function() {
console.log('--- From func ----');
console.log(this.name);
console.log(this); // this reference obj1
}
}
obj.func()
var obj2 = {
name: 'Jame Obj2',
func: obj.func // this reference obj2, but the function is defined in obj1
}
obj2.func()
var obj3 = {
name: 'Kane Obj3',
obj4: {
name: 'Mary Obj4',
func: function () {
console.log('--- From obj4 ----');
console.log(this.name);
console.log(this); // this reference obj4
}
}
}
obj3.obj4.func()
With () => {} function this - is lexically bound. It means that it uses this from the code that contains the arrow function.

What is it called when a function behaves like a class but doesn't use the class keyword, nor "new" keyword (in Javascript)?

I looked through the suggested links but can't seem to find the term for a function that acts like a class (is it a constructor function? doesn't have that keyword either!) but doesn't use the new keyword, nor class.
I've used both this example's pattern and the class pattern in my code but realized I don't know how to describe the former.
I think this is in part because I learned JS recently, have seen class thrown around a lot, yet looking through my notes of not-ES5,6,7,2018,2020 etc. can't seem to find what var aCounter = counterFunction() is called for the life of me.
I know what the result of what i'm doing is, how to work it, etc. but why no constructor(), no new, no class, no etc.prototype.etc pattern? I know i'm creating an object, calling a method existing Within the object, etc. I believe i'm beginning to ramble.
Lo, an example
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
which is || can be instantiated (?) like so:
let aCounter = counterFunction() // where i'm getting tripped up
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
I know this is rambling, but help! I think it will make things click more inside once this lexical puzzle piece is put into position!
That is just a function that returns an object literal, which does not act like a class (doesn't have a prototype, and as you pointed out, does not use new, etc).
The functions that are set as the properties of this object (which you store in aCounter) seem to act like class methods because they keep the reference to the variable val alive, but this is not because val is in any way associated with the actual object.
Instead, those functions are closures that keep the reference to the variable alive for as long as the functions themselves are alive.
So to answer your question, what you have described doesn't have any name in particular. It's just a function that returns an object.
Edit:
You asked why there is no constructor() or related syntax in this pattern. Object literals in JavaScript are just mappings of names and values:
const x = { a: 3, b: "hello" };
You do not need a constructor for this, and there is no prototype because it was not instantiated using a constructor. On the other hand, classes and constructor functions are templates for objects that will be created later, and those objects do have a prototype and a constructor because the template contains logic that initializes the object.
class A
{
constructor()
{
this.a = new Date();
this.b = this.a.toString(); // you cannot do this in an object literal
}
}
const x = new A();
Question:
What is it called when a function behaves like a class but doesn't use the class keyword, nor “new” keyword (in Javascript)?
Answer:
It's called a "factory function".
Factory functions usually return a object of a consistent type but are not instances of the factory function itself. Returned objects would rarely inherit from the factory function's prototype property, and calling the factory function does not require new before the function being called.
What you showed there is nothing special. It is just a normal function that has a closure.
Though, you can call it as a type of design pattern.
It looks similar to Revealing Module Pattern where you can separate public property and private property.
Below is an example (not a good one tho):
var counter = function(){
var privateCount = 0;
var privateHistory = [];
return {
getVal: function(){
return privateCount;
},
increment: function(){
privateCount++;
privateHistory.push('+');
return this.getVal();
},
decrement: function(){
privateCount--;
privateHistory.push('-');
return this.getVal();
},
publicHistory: function(){
return privateHistory;
}
}
}
var aCounter = counter();
console.log(aCounter.increment());
console.log(aCounter.decrement());
console.log(aCounter.publicHistory());
Here, you can't directly manipulate the private variables that I don't expose to you.
You can only manipulate those private variables only if I expose the function to you. In this case, the .increment() and .decrement() function.
As you can see, there is no class, no prototype, no constructor.
I can see how you may get tripped up, let's go through your code and explore what's going on:
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
At this point counterFunction is a variable that points to a function, it's essentially a function name. The ()=>{...} is the function body or function definition and within it the return statement shows that it returns an unnamed object with two property methods.
let aCounter = counterFunction() // where i'm getting tripped up
This is calling your previously defined function, which again returns the object with two methods and assigns it to the variable aCounter. If you did the same thing again for a variable called bCounter they would hold two independent objects.
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
Because the method inside the object refers to a variable outside the scope of the object, but within the function body, a closure is created so that the state of val may be retained. Because the variable is in use, the browser's cleanup process skips over it, so the function is still kept in memory, I believe until the object is destroyed and the function's variable is no longer used.

Differences between "this" in JavaScript and ActionScript

My background is heavy in JavaScript. I have a very advanced understanding of both ES5 and ES6. At work I was recently assigned a project involving an older flash application, which uses AS2. It is my understanding that ActionScript is very similar to ES5, but with classes and optional strict typing (akin to TypeScript and Flow), as well as a few other classic OO features. It is fairly straightforward so far, but I'm having trouble understanding how this and references work in ActionScript.
This is my understanding for JavaScript. this in a function can reference:
A bound variable, if using Function.bind() (as well as Function.call() and Function.apply()), which cannot be changed in the bound function, for example:
function func() {
return this.number;
}
var bound = func.bind({ number: 2 });
console.log(bound()); // 2
An object, if the function is called as a method on that object, for example:
function func() {
return this.number;
}
var obj = { number: 2, func: func };
console.log(obj.func()); // 2
An instance of a class, if that function is defined on the prototype of that class, for example:
function Class() {
this.number = 2;
}
Class.prototype.func = function func() {
return this.number;
}
console.log(new Class().func()); // 2
The global object, if the function is called without any kind of binding or object or instance attached to it, for example:
var number = 2;
function func() {
return this.number;
}
console.log(func()); // 2
In ActionScript things seem to be a bit different. For one thing, you can access class members without this if you are doing it within a method of that class, similar to languages like C# and Java:
class MyClass {
private var number:Number = 2;
public function func():Number {
return number;
}
}
trace(new MyClass().func()); // 2
Also, the ActionScript standard library doesn't seem to have a Function.bind() method, though it does have Function.apply() and Function.call() which seem to work just like the JavaScript variations: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/help.html?content=00001072.html#265677. There also don't seem to be prototypes, which makes sense because classes are more abstract syntactic structures rather than functions (just like C#/Java) based on my understanding.
So my question is, excluding the lack of Function.bind() and Function.prototype, are the rules the same between ActionScript and JavaScript?
In addition, what happens if I do this:
class SomeClip extends MovieClip {
private var childClip:MovieClip;
private var number:Number = 2;
public function SomeClip() {
this.onLoad = function() {
// SomeClip onLoad hander, `this` will be the SomeClip instance
childClip._visible = true; // How is childClip resolved here?
childClip.onRelease = function() {
// childClip onRelease handler, `this` will be childClip
trace(number); // How is number resolved here?
};
};
}
}
Basically, if you access a member without this in an event handler, or some other loose function that is not a method of the class, what happens? I would guess that in the first case, it would resolve to this.childClip and work as one would expect, but in the second case, the resolution would fail because the onRelease handler's closure won't contain a reference to the SomeClip instance.
I see the comments that have been written so far are more focused on JS, so I'll try my best to answer from an ActionScript perspective.
In the world of AS2/AS3, functions that are defined as methods on a class have their this value bound to the class. This is typical of many higher-level languages with modern classes, such as Java, Haxe, etc. As such, in ActionScript you'll rarely find the need to use the this keyword other than cases where a variable name might be shadowed by a function argument:
public function Point(x:Number = 0, y:Number = 0)
{
// A rare but necessary use-case of "this" in AS2/AS3
this.x = x;
this.y = y;
}
On the other hand, if the function you provide is anonymous as in the example you wrote, the behavior depends on whether or not you prepend this:
childClip.onRelease = function() {
trace(number);
};
In this case ActionScript is able to determine number is a member of the class, and will print 2 like you expected since. This is because the interpreter looks for the next closest thing in the stack. In other words, you were ambiguous by excluding this so it knows it needs to perform a lookup.
However if you were to trace(this.number) instead, you would find that you get an undefined (and possibly even an error). This is because this is not a member variable on the class, and now points to a "global object" similar to JS. To avoid dancing with the global object, it's common practice for ActionScript developers to define all of their listeners as class instance methods:
class MyClass extends EventDispatcher
{
private function MyClass()
{
addEventListener(Event.CHANGE, onChangeEvent);
}
private function onChangeEvent(e:Event) {
trace(this); // refers to this class, and no need for bind() like JS
}
}
Well organized AS3 code will almost never contain inline anonymous functions, since it's much easier to handle garbage collection by using explicit function references.
One last thing to note - you can expect functions that are methods of regular Objects in ActionScript to behave like JavaScript where passing them around via event listeners will result in the context of this being lost, and Flash will not do the magic lookup to locate the variable you referenced:
var obj = {
func: function () {
trace(this); // weird global object
}
};
addEventListener(Event.CHANGE, obj.func);
Hope that helps!
In AS2 functions are not bound and get "this" reference passed (evidently via Function.apply or by the object reference) in the moment of call:
function getIndex()
{
trace(this.index);
}
var A = {index:1, getIndex:getIndex};
var B = {index:2, getIndex:getIndex};
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 1
Binding methods to certain objects was called "delegating": http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001842.html#1001423 In a nutshell, functions are objects too and you can create special function object that has references to both method to call and "this" object to pass:
function getIndex()
{
trace(this.index);
}
function bind(method, target):Function
{
var result:Function = function()
{
// arguments.callee is always a reference
// to the current function object
arguments.callee.method.apply(arguments.callee.target);
}
result.method = method;
result.target = target;
return result;
}
var A = {index:1};
var B = {index:2};
A.getIndex = bind(getIndex, A);
B.getIndex = bind(getIndex, B);
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 2
Then, if you don't use "this" reference, once you address some variable by its name there are several contexts that are searched for such a variable in order:
local function variables
local wrapper function variables (this one is truly horrible for no one really knows where these variables exist and it is a potent memory leak)
MovieClip, that holds the function code, local variables
global variables
Play with the following code, comment some "index" variables and you'll see it:
// Global variable.
_global.index = 6;
// MovieClip local variable.
var index = 5;
function wrap():Function
{
// Wrapper function local variable.
var index = 4;
return function()
{
// Function local variable.
var index = 3;
trace(index);
}
}
wrap()();

Store "this" in TypeScript class( or maintain this in other way )

Is there a way to store the value of "this" in a TypeScript class.
Something like this( what ive used before )
Car = function() {
var _car = this;
this.speed = 0;
setInterval(function() {
_car.speed +2;
}, 32);
}
//Id like to do the same in typescript....preferably using var( not () => {} )
Is it possible ?
Yes, it is possible to achieve lexical capture of 'this' in TypeScript using a var assignment, but I would not recommend it. Lexical capture of 'this' is completely unnecessary when you understand how the JavaScript 'this' mechanism actually works.
Lexical capture of 'this' in TypeScript is usually achieved with arrow functions, but that being said, here's a sample TypeScript class that illustrates all three different ways of achieving what you want:
class Car {
speed: number
constructor() {
this.speed = 0
}
// lexical capture of 'this' with var
increaseSpeed1() {
var _car = this
setInterval(function() {
_car.speed += 2
}, 32)
}
// lexical capture of 'this' with arrow function
// (a pretty way of doing the same as above)
increaseSpeed2() {
setInterval(() => {
this.speed += 2
}, 32)
}
// binding to 'this'
// (I consider this the proper way, when you really understand how 'this' works)
increaseSpeed3() {
setInterval(function() {
this.speed += 2
}.bind(this), 32)
}
}
In increaseSpeed1, the _car object cannot be resolved within the callback to setInterval (even though the callback does have its own 'this' value), so the engine looks in the next available scope and finds the required declaration and value for _car within the scope of the increaseSpeed1 function. Here, _car has lexically captured the 'this' value of the Car class.
In increaseSpeed2, which uses the arrow function, the 'this' value of the setInterval callback is essentially thrown out, and the 'this' value from the scope of the increaseSpeed2 function (which is the same as the 'this' value of the Car class) is lexically adopted for the setInterval callback.
In increaseSpeed3, we bind to the 'this' value of the Car class. Binding to the 'this' value of the car class creates a new function from the setInterval callback that will execute in the context of the 'this' from the Car class. Like I said in the code example, this is the most proper way of achieving what you want while respecting how the JavaScript 'this' mechanism is intended to work.
Also note that should you decide that arrow functions are your preference, you can make the increaseSpeed2 function even more compact by removing the braces around the callback function body (because there is only one line of code):
increaseSpeed2() {
setInterval(() => this.speed += 2, 32)
}
Happy coding. Hope this helps!

Categories

Resources