在js中,this關鍵字的指向是一個比較重要的概念,它的值取決于函數的調用方式。
全局狀態下
//全局狀態下 this指向windowsconsole.log("this", this);console.log("this===windows", this === window);
在函數中
// 在函數中 this指向windowsfunction text() {console.log("在函數中this", this);}text();
函數作為對象的方法被調用?
// 函數作為對象的方法被調用 this指向該方法的對象const info = {name: "info",infoFunc: function () {console.log("info對象中this指向該對象", this, this.name);},};
?
構造函數中?
// 構造函數中 this指向新創建的對象function Person(name) {this.name = name;console.log("構造函數", this);}const person = new Person("zs");
?
?函數嵌套函數,使用變量存儲this,箭頭函數
const info2 = {name: "alice",// 函數嵌套函數 this 指向windowsinfo2Fun2: function () {function fun2() {console.log("函數嵌套函數中", this);}fun2();},info2Fun3: function () {//為了解決函數嵌套函數this指向windows的問題//將當前方法中的 this 值(也就是 info2 對象)存儲到 _this 變量中var _this = this;function fun3() {console.log("使用_this存儲this", _this);}fun3();},// 使用箭頭函數也可以解決函數嵌套函數 info2Fun4: function () {// 箭頭函數沒有this,向上尋找則為info2對象的thisconst fun2 = () => {console.log("info2Func2方法中的fun2函數", this);};fun2();},};info2.info2Fun2();info2.info2Fun3();info2.info2Fun4();
?
?
顯示修改this指向
在 JavaScript 中,apply、call?和 bind?是 Function 對象的三個重要方法,它們主要用于改變函數內部 this?的指向,同時還能在調用函數時傳遞參數
call
function greet(message) {console.log(`${message}, ${this.name}`);}const person2 = { name: "John" };greet(person2, "Hello1111");greet.call(person2, "Hello");
不加call為什么是[object Object],?
普通函數調用的時候 this指向全局對象,在這個調用里面,把person2作為參數傳遞給greet函數,但函數內部不指向perosn2。greet函數只接收一個參數,當調用的時候,message被賦值為perosn2,第二個參數就被忽略了。全局對象的name為空字符串,同時message是person2對象,對象默認的字符串表示形式是?[object Object]? 所以打印結果為[object Object]
console.log('window.name',window.name,typeof(window.name));
?
加call
call方法第一個參數就是要綁定給this的對象,后續參數依次傳遞給被調用的函數,當調用的時候,this被顯示地綁定到person2對象上,message被賦值為Hello
call方法支持傳入多個參數,以逗號隔開
function greet(message,message2) {console.log(`${message}, ${this.name},${message2}`);}const person2 = { name: "John" };greet.call(person2, "Hello","aaaaa");
?
apply?
apply與call類似,第一個參數都是指定函數執行時this的值,第二個參數也是傳遞數據用的,區別是它是以數組元素的形式傳入的,多個參數則傳入多個元素。當不確定參數數量的時候使用apply更方便。
greet.apply(person2,['BBBBBBBB','CCCCC'])
?
bind
bind與call和aplly類似,第一個參數也是指定函數執行時this的值,區別是call和apply會立即執行,而bind會返回一個新的函數供后續使用
const greet2=greet.bind(person2,'DDDDDD','EEEEE');greet2();
?
const greet3=greet.bind(person2,'FFFFF','GGGGGG');greet3();
?
vue中的this
選項式API
在生命周期,methods,computed,watch中,this都指向組件實例
<template><div class="box"><div @click="addNum">A:{{ num }}</div><div @click="addNum2">B:{{ num }}</div><div @click="addNum2">C:{{ num2}}</div></div>
</template><script>
export default {data(){return {num:10}},computed:{num2(){console.log('computed',this);return this.num;}},watch:{num(newvalue,oldvalue){console.log('watch',this); console.log(newvalue,oldvalue);}},created(){console.log('created中this',this);},mounted(){console.log('mounted中this',this);},methods:{addNum(){console.log('methods',this);this.num++;},addNum2:()=>{console.log('箭頭函數',this);}}}
</script>
組合式API
組合式 API 鼓勵將邏輯封裝在函數中,這些函數可以在setup函數中調用。通過這種方式,邏輯更加模塊化,作用域更加清晰。不再依賴this來訪問實例的屬性和方法,而是直接從返回的對象中解構出所需的變量和函數。
END?
?