this
makes a significant contribution to this price, around which features a lot of things are collected that can confuse a programmer.this
and a chain of prototypes. In particular, the specific value of this
inside the method is determined during the execution of the program, and the rules for determining this value vary depending on how this method was declared. const a = { a: 'a' }; const obj = { getThis: () => this, getThis2 () { return this; } }; obj.getThis3 = obj.getThis.bind(obj); obj.getThis4 = obj.getThis2.bind(obj); const answers = [ obj.getThis(), obj.getThis.call(a), obj.getThis2(), obj.getThis2.call(a), obj.getThis3(), obj.getThis3.call(a), obj.getThis4(), obj.getThis4.call(a) ];
answers
using console.log()
. Did you manage to correctly “decipher” the value of this
in each of the cases?obj.getThis()
construction returns undefined
. Why? To the arrow function this
cannot be tied. Such functions use this
from the surrounding lexical scope. The method is called in the ES6 module, in its lexical scope this
will be undefined
. For the same reason, undefined
and return call obj.getThis.call(a)
. The value of this
when working with pointer functions cannot be reassigned even with .call()
or .bind()
. This value will always correspond to this
from the lexical scope in which such functions are located.obj.getThis2()
command demonstrates how to work with this
when using the usual object methods. If this
not tied to a similar method, and provided that this method is not an arrow function, that is, it supports this
binding, the this
keyword is bound to the object for which the method is called using the property access syntax via point or using square brackets.obj.getThis2.call(a)
already a little more difficult to figure out. The call()
method allows you to call a function with a given value of this
, which is specified as an optional argument. In other words, in this case, this
is taken from the .call()
parameter, as a result, the call obj.getThis2.call(a)
returns the object a
.obj.getThis3 = obj.getThis.bind(obj);
we are trying to bind to this
method, which is a switch function. As we have already found out, this cannot be done. As a result, calls to obj.getThis3()
and obj.getThis3.call(a)
return undefined
.this
, so obj.getThis4()
, as expected, returns obj
. Calling obj.getThis4.call(a)
returns obj
, and not, as one would expect, a
. The fact is that before calling this command, we have already tied this
command obj.getThis4 = obj.getThis2.bind(obj);
. As a result, the execution of obj.getThis4.call(a)
takes into account the state of the method in which it was after the first binding.@babel/plugin-proposal-class-properties
). class Obj { getThis = () => this getThis2 () { return this; } } const obj2 = new Obj(); obj2.getThis3 = obj2.getThis.bind(obj2); obj2.getThis4 = obj2.getThis2.bind(obj2); const answers2 = [ obj2.getThis(), obj2.getThis.call(a), obj2.getThis2(), obj2.getThis2.call(a), obj2.getThis3(), obj2.getThis3.call(a), obj2.getThis4(), obj2.getThis4.call(a) ];
answers2
.obj2.getThis2.call(a)
, will return a reference to the object instance. The same call will return object a
. Arrow functions still take this
from the lexical scope. The difference between this example and the previous one is the difference in scopes from which this
is taken. class Obj { constructor() { this.getThis = () => this; } ...
new
(if you forget about this keyword, you will get an error message).new
keyword are to create a new instance of the object and to link this
to the constructor. This feature, taking into account what we have already said in the previous section, should help you understand what is happening.this
keyword behaves in JavaScript will save you a lot of time when debugging when looking for unclear reasons for incomprehensible errors. If you answer some of the questions incorrectly, it means that it will be useful for you to practice.this
quite a few developers, and I think that only one of them was absolutely accurate in all of their answers..call()
, .bind()
or .apply()
, began to look much more complicated after the appearance of pointer functions and classes.this
. Remember that the arrow functions always use this
from their lexical scope, and the keyword this
in classes is actually tied to a class constructor function. And if you ever feel that you don’t know exactly what this
indicates, use the debugger to check your assumptions about this.this
in the code. Experience tells me that virtually any JS code can be rewritten as pure functions that take all the arguments with which they work, in the form of an explicitly given list of parameters ( this
can be perceived as an implicitly specified parameter with a mutable state). The logic contained in pure functions is deterministic, which improves their testability. Such functions have no side effects, which means that when working with them, in contrast to manipulations with this
, you are unlikely to “break” anything outside of them. Whenever you change this
, you face a potential problem, which is that something depending on this
may stop working correctly.this
is a useful concept. For example, it can be applied in order to organize the sharing of a certain method by a set of objects. Even in functional programming, this
can be useful for calling an object of its other methods from one method, which allows you to create something new on the basis of existing structures.Source: https://habr.com/ru/post/455527/
All Articles