I have a script which is using bind method in VueJS. The purpose of the filter is to return people basing on gender or all.
I have the HTML code:
<div id="demo">
<div class="radio">
<label>
<input type="radio" name="gender" v-model="gender" value="all"> All
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" v-model="gender" value="male"> Male
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" v-model="gender" value="female"> Female
</label>
</div>
<ul>
<!-- Don't forget about Vue's filterBy filter. This is only for ex. -->
<li v-for="person in people | gender">{{ person.name }}: {{ person.gender }}</li>
</ul>
</div>
Below is the JavaScript code:
new Vue({
el: '#demo',
data: {
gender: 'all',
people: [
{ name: 'Jeff', gender: 'male' },
{ name: 'Jack', gender: 'male' },
{ name: 'Steven', gender: 'male' },
{ name: 'Kate', gender: 'female' },
{ name: 'Susan', gender: 'female' },
{ name: 'Claire', gender: 'female' }
]
},
filters: {
gender: function(people) {
if (this.gender == 'all') return people;
return people.filter(function(person) {
return person.gender == this.gender;
}.bind(this));
}
}
});
I don't quite understand what bind(this) does in this situation. Can anyone explain it to me? Thanks,
So this is about closures and context of this
. When you bind(this) to a function, it changes the context (or "lexical scope") of this
to within the bound function, this
remains in the outer closure rather than inside the function that is bound, thus making methods and properties available from that outer scope.
In your example, you are making Vue's data property 'gender' (which is equal to 'all') - which you referenced as this.gender
- available within the gender() function's closure, whereas otherwise it would be undefined.
As a note, this is very common pattern with ES5. But if you move to arrow functions of ES6, because it is so common, this binding is actually the default. Your gender() function would be written as this in ES6.
gender (people) => {
if (this.gender == 'all') return people
return people.filter((person) => person.gender === this.gender)
}
Much more concise and no need to bind the this
:)
Update: 2019 - I also would not use a variable and a function with the same name - this.gender (variable) and this.gender() (function).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With