先作一個小測試,若是所有答對了,恭喜你不用往下看了。數組
<script> var str = 'zhangsan'; function demo() { var str = 'lisi'; alert(this.str); } window.demo(); // ?? var obj = { str: "wangwu", say: function() { alert(this.str); } } obj.say(); // ?? var fun = obj.say; window.fun(); // ?? </script>
<script> var username = 'zhangsan'; (function() { var username = 'lisi'; alert(this.username); // ?? })() function demo() { var username = 'wangwu'; function test() { alert(this.username); } test(); // ?? } demo(); </script>
<script> function Person() { this.username = 'zhangsan'; this.say = function() { alert('我叫' + this.username); } } var p = new Person(); p.say(); // ?? var p1 = new Person(); p1.say(); // ?? </script>
<script> var username = 'zhangsan'; function demo() { alert(this.username) } var obj1 = { username: "lisi" }; var obj2 = { username: "wangwu" }; demo(); // ?? demo(obj1); // ?? demo(obj2); // ?? demo.call(obj1); // ?? demo.apply(obj2); // ?? </script>
第一題:zhangsan wangwu zhangsan 第二題:zhangsan zhangsan 第三題:我叫zhangsan 我叫zhangsan 第四題:zhangsan zhangsan zhangsan lisi wangwu (往下看,下面有詳細解析哦)
指向調用函數的對象app
無對象調用函數/匿名函數自調用(this指向window)函數
經過new產生的對象測試
apply/call調用this
<script> // this:指向調用函數的對象 var str = 'zhangsan'; function demo() { var str = 'lisi'; //this->window console.log(this); alert(this.str); } window.demo(); // zhangsan var obj = { str: "wangwu", say: function() { // this->obj alert(this.str); } } obj.say(); // wangwu var fun = obj.say; window.fun(); // zhangsan </script>
全局函數(demo)屬於window對象的方法,window調用demo因此this就指向了window指針
obj調用say方法,this就指向了objcode
fun()是全局函數,而聲明的fun接收的是obj裏面單純的一個函數,並無調用(obj.say()纔是調用了函數),此時的fun就是一個函數(function(){alert(this.str);}),那麼當fun()調用函數的時候,this指向的就是window對象
是誰調用的函數,那麼this就指向誰ip
<script> // 2.匿名函數自執行|匿名函數|無主函數 this->window var username = 'zhangsan'; // 匿名函數自執行 this->window (function() { var username = 'lisi'; console.log(this); // window alert(this.username); // zhangsan })() function demo() { var username = 'wangwu'; // 無主函數 this->window function test() { // this->window alert(this.username); } test(); // zhangsan } demo(); </script>
由於匿名函數沒有名字,因此就掛給window了io
test(),誰調用test那麼就指向誰。固然實驗過,它不是window調用的,也不是demo調用的,沒有人管它,那麼它就指向window。它就至關於一個沒有主人調用它,無主函數。
<script> // 3.經過new的對象:this指向產生的對象 // 函數 function Person() { // 屬性 this.username = 'zhangsan'; // 方法 this.say = function() { // this->p console.log(this); // Person對象 alert('我叫' + this.username); } } // 實例化出一個對象:p就具備了username屬性和say方法 var p = new Person(); console.log(p); // Person對象 console.log(p.username); // zhangsan p.say(); // 我叫zhangsan // this->p1 var p1 = new Person(); p1.say(); // Person對象 我叫zhangsan </script>
當咱們的函數Person裏面運用了this去寫屬性和方法這種格式,那麼就要經過new來讓屬性和方法變得有價值,經過new去運用函數裏面的屬性和方法
首先咱們來了解下apply()/call()是個什麼東西呢?
apply()/call():最終是調用function,只不過內部的this指向了thisObj function.call([thisObj[,arg1[, arg2[, [,.argN]]]]]) function.apply([thisObj[,argArray]]) 注意: 1. 調用function函數,可是函數內的this指向thisObj(更改對象內部指針) 2. 若是thisObj沒有傳參,則默認爲全局對象 3. call()/apply()聯繫與區別 聯繫:功能同樣,第一個參數都是thisObj 區別:傳遞的參數若是比較多 call()的實參就是一一列出 apply()的實參是所有放置在第二個數組參數中
一個理解apply()/call()的實例:
<script> // apply()/call() function demo() { console.log(123); } // 調用函數的時候,demo.call()/demo.apply()最終調用的仍是demo() demo(); // 123 demo.call(); //123 demo.apply(); // 123 </script> <script> // call()/apply()的區別: // call()參數單獨再call中羅列 // apply()的參數經過數組表示 function demo(m, n, a, b) { alert(m + n + a + b); } demo(1, 5, 3, 4); // 13 demo.call(null, 1, 5, 3, 4); // 13 demo.apply(null, [1, 5, 3, 4]); // 13 </script>
this的第四個用法實例
<script> // this的第四個用法:call(obj)/apply(obj):強制性的將this指向了obj var username = 'zhangsan'; function demo() { alert(this.username) } var obj1 = { username: "lisi" }; var obj2 = { username: "wangwu" }; // call()/apply():打劫式的改變了this的指向 demo(); // zhangsan demo(obj1); //zhangsan demo(obj2); //zhangsan demo.call(obj1); // lisi demo.apply(obj2); // wangwu </script>
若是直接調用demo裏面寫的無論是obj1仍是obj2,那麼demo仍是屬於window調用的。
無論你用call仍是apply最終調用的都是demo函數,但它們會強制的this指向了obj1/obj2,強制的指向了它們的第一個參數對象。