<!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 }