如何更改调用 Vue 实例方法的 `this` 上下文?
How to change `this` context calling Vue instance methods?
.call
、.apply
、.bind
Function.prototype
的方法不适用于在 .vue
文件中定义为 Vue 实例方法的函数。
我正在使用 @vue/cli
项目,用 vue-cli-service serve
编译。
这是简化的代码示例,可以放在任何 Vue 单文件组件定义中。
methods: {
foo() {
console.log(this);
}
},
created() {
this.foo.call({ bar: 42 });
this.foo.apply({ bar: 42 });
this.foo.bind({ bar: 42 })();
}
控制台的预期输出是三倍 { bar: 42 }
,因为这些调用的 this
值已更改。
然而,VueComponent
对象被打印到控制台。
我检查了这些重载方法,使用
this.foo.bind === Function.prototype.bind // returns true
,
他们没有超载。
可能是Vue使用了Proxy
个对象,甚至是模板编译造成的
最简单的 @vue/cli
项目加上上面的代码就足以重现问题。
谢谢
Vue 组件方法绑定到上下文,即组件实例。这可以通过以下方式检查:
function foo() {
foo() {
console.log(this);
}
}
...
methods: { foo },
created() {
this.foo !== foo // true
}
...
this.foo.bind === Function.prototype.bind
check 不具有代表性,因为 this.foo
是常规函数,所以它继承了 bind
.
一旦函数被绑定,就不能重新绑定或用不同的上下文调用:
const context = {};
const boundFoo = (function foo() { return this; }).bind(context);
// boundFoo.call({}) === context
// boundFoo.bind({})() === context
在 JS OOP 中依赖任意动态 this
上下文不是一个好习惯。如果方法需要上下文,则应将其作为参数提供给它:
methods: {
foo(ctx) {
console.log(ctx);
}
},
created() {
this.foo({ bar: 42 });
}
或作为实例共享 属性,具体取决于用途。
.call
、.apply
、.bind
Function.prototype
的方法不适用于在 .vue
文件中定义为 Vue 实例方法的函数。
我正在使用 @vue/cli
项目,用 vue-cli-service serve
编译。
这是简化的代码示例,可以放在任何 Vue 单文件组件定义中。
methods: {
foo() {
console.log(this);
}
},
created() {
this.foo.call({ bar: 42 });
this.foo.apply({ bar: 42 });
this.foo.bind({ bar: 42 })();
}
控制台的预期输出是三倍 { bar: 42 }
,因为这些调用的 this
值已更改。
然而,VueComponent
对象被打印到控制台。
我检查了这些重载方法,使用
this.foo.bind === Function.prototype.bind // returns true
,
他们没有超载。
可能是Vue使用了Proxy
个对象,甚至是模板编译造成的
最简单的 @vue/cli
项目加上上面的代码就足以重现问题。
谢谢
Vue 组件方法绑定到上下文,即组件实例。这可以通过以下方式检查:
function foo() {
foo() {
console.log(this);
}
}
...
methods: { foo },
created() {
this.foo !== foo // true
}
...
this.foo.bind === Function.prototype.bind
check 不具有代表性,因为 this.foo
是常规函数,所以它继承了 bind
.
一旦函数被绑定,就不能重新绑定或用不同的上下文调用:
const context = {};
const boundFoo = (function foo() { return this; }).bind(context);
// boundFoo.call({}) === context
// boundFoo.bind({})() === context
在 JS OOP 中依赖任意动态 this
上下文不是一个好习惯。如果方法需要上下文,则应将其作为参数提供给它:
methods: {
foo(ctx) {
console.log(ctx);
}
},
created() {
this.foo({ bar: 42 });
}
或作为实例共享 属性,具体取决于用途。