why should I use bind(this) with a method in a class? - javascript

Given the documentation
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
I'm currently following a tutorial about creating a blockchain using node.js
https://developers.caffeina.com/chiccocoin-learn-what-is-a-blockchain-by-creating-one-in-nodejs-12929a89208b
But what I don't understand in the following example (code provide by the tutorial I'm following) is why should I bind the keyword 'this' to a method which belong to a class. Given the function newBlock() belong of the class Blockchain, it should have access to the 'this' and all of the variable related to the class Blockchain.
class Blockchain {
constructor () {
this.chain = []
this.newBlock = this.newBlock.bind(this)
this.newBlock(100, 1)
}
newBlock (proof, previousHash) {
const block = this.chain.length + 1
}
}
Does anyone can explain me why should I use bind(this) with a method in a class ? Actually it may be possible that I misunderstood the purpose of bind(this) so that would be great if you could point me out what did I misunderstand.
Thanks :)

Bind will create a copy of the function which will guarantee that the reference of "this" in function newBlock will point to Blockchain. If a new function (let's call it function readBlocks) were to invoke newBlock, it's this context would instead point to readBlocks instead of Blockchain. Binding will allow you to use newBlock without worrying about it's this context being dynamic.

class definition the way you did, in javascript, is still doing prototypal inheritence behind the scenes. This class definition is malleable and you can add more methods to it by just adding more methods to it's prototype. So the class syntax is more like syntactic sugar (not completely, but for most practical purposes) for the normal prototypal inheritence done using functions.
Given that background, this binding in javascript was always done at runtime (except for arrow functions). The context in which a particular method is called determines the this binding. It's not bound at the time of defining the method. But that rule does not hold if you prebind the method to a particular context, like you did in your example with .bind.
If you had not done that, someone could have called the method newBlock like this
let a = new Blockchain()
let b = new Blockchain()
a.newBlock.call(b, proof, previousHash)
And since binding of this is done at runtime, in the above case, the method newBlock will be called with this refering to object b. But that will not happen if you prebind the method using .bind.
It's tricky. But main takeaway is that the runtime binding rules of this in javascript still hold for the new class syntax. Hope it helped.

Related

Still not understanding .this after reading articles

I'm a JS/React beginner who has read a few articles on the this keyword on JS, but remain confused.
Namely, I've consulted Tyler McGinnis's React and The Complete Javascript on Udemy.
This keyword is a fairly complex topic imo, but from these two sources I know .this refers to the global scope by default, but refers to the object in question when it is defined within a method. I also know that .call/apply/bind can give us a hint on what the .this refers to.
My question is, when do you actually write the .this keyword when you are writing your programs? The sources above seemed to focus on understanding why others might've used the keyword, but not necessarily when you need to do it. Thus, I always get confused when tutorials seemingly randomly throw in a this/bind etc everywhere
In terms of specific examples, I have :
1. One in the context of states:
I've encountered apps before learning about the .this concept which do not use the .this keyword. No specific examples for this, but shouldn't you use .this most of the time then?
Apologies if this is a silly question -- sometimes I wonder whether it is better to analyze/dissect the rationale for each part in coding or just to learn coding as just the way things are much like a child learns a language naturally without questioning grammar rules
In this example, we are passing down a prop called onDelete, but I do not understand why we need to bind. Does this mean we are binding the passed down onDelete to props.id which was also passed down?
The important part is you took the time to research. Personally I do not recommend using React to learn about this. When you extend a React component, your this prototype inherits from React.Component, so there's a lot of React-specific conventions there already. Instead, consider this example where I call this directly
function SimpleQueue({ size }) {
this.size = size
this.buffer = []
}
SimpleQueue.prototype.push = function(item) {
this.buffer.push(item)
if (this.buffer.length > this.size) {
this.buffer.shift()
}
return this
}
SimpleQueue is just a simple queue implementation using an internal array. You can think of this as a reference to the current instance of SimpleQueue, whatever that may be. I use this specifically in the example above to access the internal array as this.buffer. I can then use an instance of a SimpleQueue like so
const mySimpleQueue = new SimpleQueue({ size: 3 })
mySimpleQueue.push(1) // SimpleQueue { 1 }
mySimpleQueue.push(2) // SimpleQueue { 1, 2 }
mySimpleQueue.push(3) // SimpleQueue { 1, 2, 3 }
mySimpleQueue.push(4) // SimpleQueue { 2, 3, 4 }
Note: my example does not use class, but it is the same because classes are syntactic sugar for the prototype-based programming model
shouldn't you use .this most of the time then?
Yes, for class based react components, you should almost everywhere use this., for access props, state, handlers, calling methods etc.
constructor is an exception ... this.state is created, props are constructor argument.
Handlers declared using handleChange(e) {} syntax needs .bind(this) to be able:
to operate on this.state;
to use this.setState() (react component method derived from base class);
to use other methods defined in this component.
Usually event handlers are binded in constructor in the form like:
this.handleChange = this.handleChange.bind(this);
<button onClick={this.handleClick} />
Event handlers defined using ES6 'arrow syntax' fn = () => {} are autobinded to this.
Also handlers defined using 'normal function syntax' but assigned using 'arrow syntax' in render doesn't need binding:
<button onClick={(e) => this.handleClick(e)} />
Bad news - every render call crates new ref ... at least not optimal in react ... so ... use arrow declaration (or bind in constructor).
we are passing down a prop called onDelete, but I do not understand why we need to bind
Why? Probably passed handler not binded - rare requirement to bind handler to different object/component context (different this).
"this" is not a complex topic. people make it complex.
you have
handleTitleChange=(title)=>{
this.setState({})
}
When you say this.setState() you want this to refer the class component that you defined the handleTitleChange() inside. Arrow functions AUTOMATICALLY allow you to set “this” when the function is defined. That is why it is said that arrow functions are lexically bound to this. When our component is getting rendered by javascript for the first time, it checks inside and sees that there is handleTitleChange() points to arrow function. The moment it sees “this”, it is going to automatically bind “this” to the place where the arrow function is defined in the the first place. The context of that function is the TimerForm component.
But by default javascript does not set its scope of “this” on functions. "this" is dynamically scoped, it does not matter where the function is written, it matters how the function is called. That is why we have to actually explicitly state what context you want “this” to be for us. We want “this” to be our class component and the method in which we can do it is to define in our constructor(). If you write above code like this :
handleTitleChange(title){
this.setState({})
}
Now,in the above function this refers to the class but when you pass the reference to be called by another component or function, you are not passing its "this" anymore. New "this" will be assigned by object which calls "handleTitleChange(title)". We have to make sure that when we call handleTitleChange(title), its "this" value always points to TimerForm class. So we go to constructor(){}. Because our constructor() is the code that runs first before anything gets called. We want to make sure that the context of this is correct in all of our methods before any code gets written.
constructor(){
super()
console.log(this) // it will log TimerForm class
this.handleTitleChange=this.handleTitleChange.bind(this)
//bind(this) `this` refers to the TimerForm
}
bind() is a method on any function that returns a new function with a new execution context. now our handleTitleChange method learnt that this inside of it, will refer to the TimerForm class component.
to your 3rd question. props.onDelete is a function that's passed down, it's binding on this, which is the current execution context in <TouchableOpacity>, props.id is the argument of the onDelete function.
this is the old way, I believe an arrow function will do the same thing, () => props.onDelete(props.id)
And in react world/javascript land, function components/object destructing/arrow function are taking more ground these days, might be a reason you see less/none this in the codebase.

What is this() in javascript?

I understand the this keyword in javascript. I have used it like this.method() or this.variable =. But what is this(). See the below code:
static fromTX(tx, index) {
return new this().fromTX(tx, index);
}
Please help me understand the use of this() in javascript and in the above code example.
Inside a static method, this will refer to the constructor, so new this() will invoke the constructor:
class Foo {
constructor() {
console.log('making instance');
}
static makeFoo() {
return new this();
}
}
const f = Foo.makeFoo();
Of course, invoking this like that is only possible when this refers to a function, otherwise it'll throw an error. Usually, this will refer to an object, not a function.
Let us take a 2-way approach to the problem:
First, this refers to the current instance within the class and is a keyword in numerous languages.
this() is a call to the constructor and this can contain various parameters as well.
Second, looking at the code snippet, it is a static method- precisely a static factory method. Look it up to understand why and where to use it and more details.
The snippet provides an API to create the class object from params tx, index. You would want to do it to make it more readable for the client who calls this API. It is safe to assume that you might have different APIs too in this method solely for creating an object of the class. Further, in such cases, the constructors are marked private to gain more control over the object instantialtion.

What does prototype methods don't bind on extraction mean?

When reading why ES6 class methods don't automatically bind "this" to the method, I see answers that say "prototype methods don't bind on extraction", but that means nothing to me. What does "bind on extraction" mean?
When a function is called
obj.func()
What does "binding on extraction mean"?
Articles I found that are relevant are:
https://esdiscuss.org/topic/why-are-es6-class-methods-not-automatically-bound-to-the-instance - This is the article that generated my question. Search for "we could still have had methods bind on extraction"
Why aren't methods of an object created with class bound to it in ES6? - this is the Stack Overflow question and answer that references the article in question.
Mozilla MDN web docs on Classes - Strangely enough, the Rectangle example given as an example Javascript class doesn't use bind(). I'm guessing because it was so simple bind wasn't needed, but if it had, it would help the folks (like myself) that came to Javascript from a Java background
ES6 In Depth: Classes - very good article on prototype objects and how the class keyword is syntactic sugar.
Extraction basically means disconnecting the method from the object. You do this any time you call the method without "chaining" it to the class instance.
class Test {
constructor(r) {
this.r = r;
}
sample() {
console.log(this);
}
}
let t = new Test(1);
t.sample();
let q = t.sample;
q();
So in this example, when I call t.sample(), it returns exactly what I expect: { r:1 }. But when I set q = t.sample and then invoke q(), I get undefined. I've "extracted" my function and assigned it to a different variable.
This same thing happens if you use the function as an event handler.
Imagine you had some class:
class C {
foo() {
console.log(this);
}
}
and somebody does:
const c = new C();
const o = {
callback: c.foo // "extract the function"
}
o.callback();
Which object should be logged to the console? c, because it originally declared the method, or o because that's what we specified at the call site?
JavaScript defaults to the latter, but you can achieve the former by calling Function.prototype.bind.
That is, the question they were discussing was whether class methods should automatically bind to this when being retrieved from an object, ensuring that this always refers to the object the method originally came from, as opposed to the object the caller uses to make the call.

Better way to access variables across prototype methods in JavaScript?

I often use the pattern of a main JavaScript constructor function and adding methods to its prototype object so they can be called intuitively by the user, for example:
function Slideshow(options) {
this.options = options
this.slideshow = $('#slideshow')
//more variables here
}
Slideshow.method1 = function () {
this.slideshow.addClass('test') // do something with slideshow variable
};
Slideshow.method2 = function () {
// another method
};
The one thing that really bugs me about this pattern is how in order to make variables accessible across all prototype methods, I have to add "this" in front of each variable inside the constructor function. It's a major pain, and I can't help but think there's a more elegant way to do this.
If I forgo using the prototype object and just add the methods as instance methods, I know I can't get around this problem, but I like the efficiency? and self encapsulating nature of this pattern. Any other suggestions for a better pattern? Thanks!
It's a major pain
No, it's really not. Every single JavaScript developer uses this syntax. If you were in Ruby or Python, you'd use self., in PHP you'd use $this->. Some languages like C++ don't require any special decorator, but JavaScript does.
and I can't help but think there's a more elegant way to do this.
No, there isn't.
This is JavaScript's syntax, you cannot change it, and you cannot work around it. If you want to access a property of this, you need this. before the property name. Otherwise, you're talking about global variables.
If you want a different syntax, consider a different language like CoffeeScript, which compiles to JavaScript.
meager has pretty much summed things up if you're talking about accessing public instance properties or methods. You have to use this in front of it as that's just how the language works.
But, if you have private instance properties or methods, you can define those as local variables inside the constructor and you can access them without this.
function slideshow(options) {
// no need to resave the options arguments as they can be used
// directly from the argument variable
// define a per-instance private variable that other methods defined
// within the constructor can use directly without the use of `this`
var theShow = $(options.selector || '#slideshow');
// define public methods
this.method1 = function() {
// can access private instance variable here without this in front of it
theShow.addClass('test');
}
this.method2 = function() {
theShow.addClass(options.decoaration);
}
}
This general design pattern is described here: http://javascript.crockford.com/private.html
Practically speaking, this works because the constructor function with the public methods declared inside it creates a closure that lasts for the duration of the object lifetime so the local variables in the constructor become per-instance variables accessible only from the functions declared within the constructor.

Need help / Creating Methods via prototype property

Please help me to understand below code. This is the script for drag and drop object. I am trying to explore it but struck at one thing.
URL for Reference (Complete Script)
I dont understand how this method creation work, like get x(), set x() etc. Is get and Set is predefined object? will it actually set object value or get specific value of object, like we have in date object.
Also there is one space between its declaration set x(), why?
I am new to java script, i really appreciate your help.
// position strings are "x,y" with no units
get x()
{
return parseInt(this._position.split(',')[0]);
},
set x(inX)
{
var comps = this._position.split(',');
comps[0] = inX;
this.position = comps.join(',');
},
get y()
{
return parseInt(this._position.split(',')[1]);
},
set y(inY)
{
var comps = this._position.split(',');
comps[1] = inY;
this.position = comps.join(',');
},
Let's start by calling the language 'JavaScript' not 'java script'; the language is standardized as Ecmascript.
Look up creation of methods in Ecmascript (JavaScript). The functions set(inX) and get() are methods be of some prototype - the clue is the this reference referencing the current instance. However, one should write function get(), and function set(inX) instead.
From Wikipedia:
Prototype-based
prototypes
JavaScript uses prototypes instead of classes for inheritance. It
is possible to simulate many class-based features with prototypes in
JavaScript. functions as object constructors
Functions double as object constructors along with their typical
role. Prefixing a function call with new creates a new object and
calls that function with its local this keyword bound to that object
for that invocation. The constructor's prototype property determines
the object used for the new object's internal prototype. JavaScript's
built-in constructors, such as Array, also have prototypes that can be
modified. functions as methods
Unlike many object-oriented languages, there is no distinction
between a function definition and a method definition. Rather, the
distinction occurs during function calling; a function can be called
as a method. When a function is called as a method of an object, the
function's local this keyword is bound to that object for that
invocation.

Categories