Gera
Gera

Reputation: 105

How to change `this` context calling Vue instance methods?

.call, .apply, .bind methods of Function.prototype don't work for functions once defined as methods of Vue instance in .vue file.

I'm using @vue/cli project, compiled with vue-cli-service serve. Here's reduced example of code, which can be placed in any Vue single-file component definition.

    methods: {
        foo() {
            console.log(this);
        }
    },
    created() {
        this.foo.call({ bar: 42 });
        this.foo.apply({ bar: 42 });
        this.foo.bind({ bar: 42 })();
    }

Expected output to the console is triple { bar: 42 }, since this value was changed for these calls. However, VueComponent object is printed to the console.

I checked these methods for overloading, using this.foo.bind === Function.prototype.bind // returns true, they are not overloaded.

It may be caused by Vue using Proxy objects or even by templates compilation.

Simplest @vue/cli project with code above will be enough to reproduce the problem.

Thanks

Upvotes: 4

Views: 959

Answers (1)

Estus Flask
Estus Flask

Reputation: 222309

Vue component methods are bound to the context, which is component instance. This could be checked with:

function foo() {
    foo() {
        console.log(this);
    }

}

...
methods: { foo },
created() {
    this.foo !== foo // true
}
...

this.foo.bind === Function.prototype.bind check isn't representative since this.foo is regular function, so it inherits bind.

Once a function is bound, it cannot be re-bound or be called with different context:

const context = {};
const boundFoo = (function foo() { return this; }).bind(context);
// boundFoo.call({}) === context
// boundFoo.bind({})() === context

It isn't a good practice to rely on arbitrary dynamic this context in JS OOP. If a method needs a context, it should be provided to it as an argument:

methods: {
    foo(ctx) {
        console.log(ctx);
    }
},
created() {
    this.foo({ bar: 42 });
}

Or be shared as instance property, depending on the purpose.

Upvotes: 3

Related Questions