對this我想做爲前端來講接觸的是不少的,可能只限於能用的層次,就不少面試題來講,要徹底弄懂仍是有點距離的,那麼咱們就來增強理解下吧,參考高三和語言精粹。javascript
this和arguments是做爲函數的兩個特殊對象的,參數this在面向對象編程中很是重要,它的值取決於調用的模式,在js中一共有4種調用模式,html
當一個函數保存爲一個對象的屬性時,咱們稱之爲一個方法,當這個方法被調用的時候,this就被綁定到該對象,前端
var o = { val: 0, sayval: function(num){ if(typeof num === 'number'){ console.log(this.val + num) }else{ alert('請輸入數字') } } } var val = 11; o.sayval(1);//1 o.sayval(2);//2
當一個函數並不是一個對象的屬性時,那麼它就是被當作一個函數調用的,當函數以此模式調用時,this被綁定到全局對象,java
var o = { val: 0, sayval: function(num){ if(typeof num === 'number'){ console.log(this.val + num) }else{ alert('請輸入數字') } } } var val = 11; var fn = o.sayval; fn(1);//12
這樣設計的話,當內部函數被調用的時候,this應該綁定到外部函數的this變量,可是卻被綁定到了全局,這裏有個解決的辦法,定義一個變量並給它賦值爲this,面試
var o = { val: 0, sayval: function(num){ var that = this; var other = function() { if(typeof num === 'number'){ console.log(that.val + num) }else{ alert('請輸入數字') } }; other(); } } var val = 11; o.sayval(1);//1 方法調用模式
這裏是否是有點混了,剛開始我也有點混淆了,剛講過,方法調用模式this會被綁定到全局,怎麼這樣作倒是綁定到o這個對象了呢,區別在於第7行,如果將that改成this,結果就是12了,在這大膽的分析下函數執行邏輯吧,若是是this,方法調用,綁定到全局對象,this就是window.this,若是是that就不同了,that是變量,那函數執行的時候就會根據做用域去尋找這個變量值,other函數沒有就向上找,(變量做用域的知識),找到sayval裏面的that,這個變量指向的this,而這裏的this指的就是o這個對象。編程
這樣給咱們的啓示是若是想調用這個函數的外部函數的屬性,就在外部函數保存this值,再在內部函數中調用,而後再用方法調用模式去調用函數。數組
做爲瀏覽器兼容性中很重要的一條:element.attachEvent綁定事件方法,當該事件觸發時this指針並未綁定到element對象上,而是綁定到了window對象上,緣由在於IE中事件觸發時,響應函數是以一個獨立函數即函數調用模式來調用的。瀏覽器
javascript 是一門基於原型繼承的語言,這意味着對象能夠直接從其餘對象繼承屬性。app
若是在一個函數前面帶上new來調用,那麼將建立一個隱藏鏈接到該函數的prototype成員的新對象,同時this將會被綁定到那個新對象上,new前綴會改變return語句的行爲。函數
var P = function(n){ this.name = n; } P.prototype.getName = function(){ console.log(this.name); } var p = new P('jesse'); // 這時P中的this對象唄綁定p指向的對象引用上 p.getName();//jesse
同時new運算符還會改變函數的返回值。以函數調用模式調用P即P()返回undefined,而經過new運算符則返回一個新對象。
apply方法讓咱們構建一個參數數組傳遞給調用函數。它也容許咱們選擇this的值,apply的方法接受兩個參數,第1個是要綁定給this的值,第2個是參數數組(call的話後邊是一個一個的參數)。
var add = function(a, b){ return a + b; }; var arr = [3, 4]; var sum = add.apply(null, arr); console.log(sum);//7