方法自執行時,this指向window,被對象調用時,this指向對象。
能夠用call(),apply()和bind()改變this指向。
全局環境中this默認綁定到windowjson
<script> console.log(this); //window </script>
函數獨立調用,this默認綁定到window數組
<script> function func(){ console.log(this); //window }; func(); </script>
被嵌套的函數獨立調用,this默認綁定到window閉包
<script> var a = 0; // Window中的a var obj = { a : 1, // obj中的a func : function(){ var a = 2 // func中的a function test(){ var a = 3; // test中的a console.log(this.a) // this指向Window }; test(); } }; obj.func(); </script>
閉包中函數獨立調用,而不是方法調用,this默認綁定到windowapp
<script> var a = 0; // Window中的a function func(){ var a = 1; // func中的a function test(){ var a = 3; // test中的a console.log(this.a); //this指向Window } return test(); }; func(); </script>
通常被直接對象包含的函數調用時,也叫方法調用,this存在隱式的綁定到該對象函數
<script> var a = 0; function func(){ console.log(this.a); }; var obj1 = { a : 1, func : func, obj2 : { a : 2, func : func, }, }; obj1.func(); // 1 obj1.obj2.func(); // 2 </script>
隱式丟失是指被隱式綁定的函數丟失綁定對象,從而默認綁定到windowthis
<script> var a = 0; function func(){ console.log(this.a); }; var obj1 = { a : 1, func : func, obj2 : { a : 2, func : func, }, }; obj1.func(); // 1 這是一個對象下的方法隱式綁定,因此對象是obj1 var bar = obj1.func; // 把obj1.func賦值給bar變量,形成隱式丟失,由於這個變量和對象obj1毫無關係 bar(); // 0 </script>
函數在做爲一個參數傳遞的時候,會隱式丟失,this默認指向Windowcode
<script> var a = 0; function func(){ console.log(this.a); }; function bar(fn){ fn(); }; var obj = { a : 1, func : func, }; obj.func(); // 1 這是一個對象下的方法隱式綁定,因此對象是obj1 bar(obj.func); // 0 把函數做爲參數傳遞,會形成隱式丟失 </script>
開啓嚴格模式: "use strict",避免未聲明變量泄露對象
<script> "use strict" // 開啓嚴格模式 a = 0; // a會泄露到Window中 console.log(this.a); // 嚴格模式開啓,此處結果爲0; 嚴格模式未開啓,此處結果爲 a is not defined </script>
call() 會自執行事件
1.當call()不傳遞參數的時候,this默認指向window
2.當call()傳遞參數時,,第一個參數必須指向某一個對象,後面的參數是實參ip
<div id="box">box</div> <script> let a = 1; let b = 2; let json = { a : 3, b : 4, }; function func(){ console.log(this.a + this.b) // 此處this的指向根據調用方不一樣,指向不一樣的地方 } func(); // NaN 由於let不會泄露到Window,因此this指向的Window中沒有a和b let box = document.getElementById("box"); // 獲取box對象 box.a = 10; // 設置box對象屬性a的值爲10 box.b = 20; // 設置box對象屬性b的值爲20 // box.onclick = func; // 30 設置box對象onclick事件,點擊box對象,this指向box對象,得到結果爲30 // box.onclick = func.call(); // NaN 當call()不傳遞參數的時候,this默認指向window box.onclick = func.call(json); // 7 當call()傳遞參數時,,第一個參數必須指向某一個對象,後面的參數是實參 </script>
apply() 會自執行
1.接收兩個參數,第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參
<script> let a = 1; let b = 2; let json = { a : 3, b : 4, }; function func(a, b){ console.log(this.a + this.b); console.log(a + b) } func.apply(window, [3,3]); // NaN 6 第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參 func.apply(json, [3,3]); // 7 6 第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參 </script>
bind() 不會自執行
<div id="box">box</div> <script> let box = document.getElementById("box"); // 獲取box對象 let json = { a : 3, b : 4, } function func(a, b){ console.log(this.a + this.b); console.log(a + b); } box.onclick = func.bind(json, 3, 3); // 7 6 點擊box對象後執行函數,無參數指向Window </script>
點擊一個對象時,使用另外一個對象的屬性
<div id="box1">box</div> <div id="box2">box2</div> <script> let box1 = document.getElementById("box1"); // 獲取box1對象 box1.a = 1; box1.b = 2; let box2 = document.getElementById("box2"); // 獲取box2對象 box2.a = 3; box2.b = 4; function func(){ console.log(this.a + this.b); } box1.onclick = func.bind(box2); // 7 點擊box1時,使用box2的屬性 </script>