Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind Function Meaning in VueJS

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,

like image 508
Dale Nguyen Avatar asked May 11 '16 18:05

Dale Nguyen


1 Answers

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).

like image 118
Tremendus Apps Avatar answered Sep 27 '22 18:09

Tremendus Apps