vue中的this指向问题
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script> <script src="https://unpkg.com/vue@2.5.9/dist/vue.js"></script> </head> <div id="app" style="width: 100%;height: auto;font-size:20px;"> <p id="id1"></p> <p id="id2"></p> </div> <script type="text/javascript"> var message = "Hello!"; var app = new Vue({ el:"#app", data:{ message: "你好!" }, created: function() { this.showMessage1(); //this 1 this.showMessage2(); //this 2 }, methods:{ showMessage1:function(){ setTimeout(function() { document.getElementById("id1").innerText = this.message; //this 3 }, 10) }, showMessage2:function() { setTimeout(() => { document.getElementById("id2").innerText = this.message; //this 4 }, 10) } } }); </script> </html>
第一个输出英文"Hello!”,第二个输出中文“你好!”。这说明了showMessage1()里的this指的是window,而showMessage2()里的this指的是vue实例。
※ 对于普通函数(包括匿名函数),this指的是直接的调用者,在非严格模式下,如果没有直接调用者,this指的是window。showMessage1()里setTimeout使用了匿名函数,this指向
window。
※ 箭头函数是没有自己的this,在它内部使用的this是由它定义的宿主对象决定。showMessage2()里定义的箭头函数宿主对象为vue实例,所以它里面使用的this指向vue实例。
注:
【普通函数的this】
普通函数的this是由动态作用域决定,它总指向于它的直接调用者。具体可以分为以下四项:
this总是指向它的直接调用者, 例如 obj.func() ,那么func()里的this指的是obj。
在默认情况(非严格模式,未使用 'use strict'),如果函数没有直接调用者,this为window
在严格模式下,如果函数没有直接调者,this为undefined
使用call,apply,bind绑定的,this指的是绑定的对象
绑定vue实例到this的方法
为了避免this指向出现歧义,有两种方法绑定this。
使用bind
showMessage1()可以改为:
showMessage1:function(){
setTimeout(function() {
document.getElementById("id1").innerText = this.message; //this 3
}.bind(this), 10)
}
对setTimeout()里的匿名函数使用bind()绑定到vue实例的this。这样在匿名函数内的this也为vue实例。
把vue实例的this赋值给另一个变量再使用
showMessage1()也可以改为
showMessage1:function(){
var self = this;
setTimeout(function() {
document.getElementById("id1").innerText = self.message; //改为self
}.bind(this), 10
}