this
can be called one of the most discussed and ambiguous features of the language. The thing is that what it indicates looks differently depending on where this is addressed. The matter is aggravated by the fact that this
is also affected by whether strict mode is enabled or not.this
, try not to use this language construct at all. I do not see anything wrong here. On the basis of this
aversion, many useful things were created. For example, switch functions and this
binding. As a result, the development can almost completely do without this
.this
” is over? Of course not. If you think about it, you may find that tasks that are traditionally solved with the involvement of function constructors and this
can be solved in another way. This material is devoted to the description of this approach to programming: no new
and no this
on the way to simpler, more understandable and predictable code.this
. We will not consider the fundamentals of JS here, our main goal is to describe a special approach to programming, excluding the use of this
, and, thanks to this, helping to eliminate potential troubles related to this
. If you want to refresh your knowledge about this
, here and here are the materials that will help you with this. function makeAdder(base) { let current = base; return function(addition) { current += addition; return current; } }
makeAdder()
function takes a base
parameter and returns another function. This function takes a numeric parameter. In addition, it has access to the current
variable. When it is called, it adds the number passed to it to current
and returns the result. Between calls, the current
variable is preserved. let counter = (function() { let privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } }; })(); counter.increment(); counter.increment(); console.log(counter.value()); // 2
privateCounter
variable is the data we need to work with, hidden in the closure and not directly accessible from the outside. The public methods increment()
, decrement()
and value()
describe the operations you can perform with privateCounter
.this
. Consider an example.this
. This is an implementation of a known data structure called a deque (double-ended queue). This is an abstract data type that works as a queue , however, our queue can grow and shrink in two directions.data
, which will store the data of each queue element. In addition, we need pointers to the first and last elements, to the head and tail of the queue. Call them, respectively, head
and tail
. Since we create a queue based on a linked list, we need a way to connect the elements, so each element requires pointers to the next and previous elements. Let's call these pointers next
and prev
. And finally, you want to track the number of items in the queue. Use the variable length
for this.data
, as well as pointers to the next and previous nodes — next
and prev
. For these reasons, create a Node
object, which is an element of the queue: let Node = { next: null, prev: null, data: null };
head
and tail
), as well as information about its own length (variable length
). Based on this, we define the Deque
object as follows: let Deque = { head: null, tail: null, length: 0 };
Node
, which is a separate node of the queue, and a Deque
object, which represents the two-way queue itself. They need to be stored in the closure: module.exports = LinkedListDeque = (function() { let Node = { next: null, prev: null, data: null }; let Deque = { head: null, tail: null, length: 0 }; // API })();
create()
method can be described. It is pretty simple: function create() { return Object.create(Deque); }
isEmpty()
method: function isEmpty(deque) { return deque.length === 0 }
deque
, and check if its length
property is zero.pushFront()
. In order to implement it, you must perform the following operations:Node
object.Node
object.head
queue and set its prev
pointer to the new element, and set the next
pointer of the new element to the element that is written to the head
variable. As a result, the first element of the queue will be a new Node
object, followed by the element that was first before the operation. In addition, you need to remember to update the queue pointer head
so that it refers to its new element.length
property.pushFront()
method code: function pushFront(deque, item) { // Node const newNode = Object.create(Node); newNode.data = item; // head let oldHead = deque.head; deque.head = newNode; if (oldHead) { // , oldHead.prev = newNode; newNode.next = oldHead; } else {// — , tail. deque.tail = newNode; } // length deque.length += 1; return deque; }
pushBack()
method, which allows you to add elements to the end of a queue, is very similar to the one we just looked at: function pushBack(deque, item) { // Node const newNode = Object.create(Node); newNode.data = item; // tail let oldTail = deque.tail; deque.tail = newNode; if (oldTail) { // , oldTail.next = newNode; newNode.prev = oldTail; } else {// — , head. deque.head = newNode; } // length deque.length += 1; return deque; }
return { create: create, isEmpty: isEmpty, pushFront: pushFront, pushBack: pushBack, popFront: popFront, popBack: popBack }
const LinkedListDeque = require('./lib/deque'); d = LinkedListDeque.create(); LinkedListDeque.pushFront(d, '1'); // [1] LinkedListDeque.popFront(d); // [] LinkedListDeque.pushFront(d, '2'); // [2] LinkedListDeque.pushFront(d, '3'); // [3]<=>[2] LinkedListDeque.pushBack(d, '4'); // [3]<=>[2]<=>[4] LinkedListDeque.isEmpty(d); // false
LinkedListDeque
methods, as long as there is a working link to it.popBack()
and popFront()
, which, respectively, delete and return the first and last elements of the queue.ArrayDeque
. And remember - no this
and new
.MixedQueue
. With this approach, first create an array of fixed size. Let's call it block
. Let its size be 64 elements. It will store the elements of the queue. When you try to add more than 64 elements to the queue, a new data block is created, which is connected to the previous one using a linked list of the FIFO model. Implement two-way queue methods using this approach. What are the advantages and disadvantages of such a structure? Record your findings.join
, which allows you to connect two two-way queues. For example, a call to LinkedListDeque.join(first, second)
attach the second queue to the end of the first and return a new two-way queue.for
loop. For this exercise, you can use ES6 iterators .this
, and how well you understand all this. Well, do not forget to mention me .an * x^n + an-1*x^n-1 + ... + a1x^1 + a0
. Here an..a0 —
the coefficients of the polynomial, and n…1 —
exponents. Create an implementation of the data structure for working with polynomials, develop methods for adding, subtracting, multiplying, and dividing polynomials. Limit yourself to simplified polynomials. Add tests to validate the solution. Ensure that all methods that return a result return it as a two-way queue.this
are worth the effort to transition to a new programming model, take a look at eslint-plugin-fp . With this plugin you can automate code checks. And, if you work in a team, before you give up this
, agree with your colleagues, otherwise, when meeting with them, do not be surprised by their gloomy faces. Have a nice code!this
in javascript?Source: https://habr.com/ru/post/334222/
All Articles