今天跟大家一起簡單的來了解一下js中一個有趣的東西,this.
在js中我們用面向對象的思想去編寫的時候,各個模塊之間的變量就不那么容易獲取的到了,當然也可以通過閉包的方式拿到其他函數的變量,如果說每獲取一個變量,都要用閉包的方式去獲取,就顯得太繁瑣了,這時候js中也提供了一種方法來獲取其他的變量,當然前提是這些函數之間是有聯系的,比如函數2是綁在函數1的原型上的,那么函數1中用this指明的一個變量,在函數2中同樣可以用this來獲取到,當然着其中是有着一定的規則的。那么接下來我給大家對this做一個詳細的介紹
一:到底什么是this呢?
概念:執行上下文,this一般存在於函數中,表示當前函數的執行上下文, 如果函數沒有執行,那么this沒有內容,只有函數在執行后this才有綁定。
注意:this的指向只能是對象,當然別忘記了數組也是一個特殊的對象。
二:this到底指向的是誰呢?
this的指向其實是跟this的執行位置是有關的,不同的位置執行位置,this的指向就可能發生改變。
Tip:this被誰執行了,this就是執行誰的,這時候一定要看清楚this是被誰直接執行的!
那么接下來給大家總結幾種this指向的問題。
1:默認執行:this指向了window,在嚴格模式下,this指向了undefined
eg: function fn(){ "use strict"; console.log(this); } fn(); 這個時候在嚴格模式下,指向的是undefined,去掉嚴格模式,指向window
2:隱式執行(通過對象執行):通過上下文對象執行
這里給大家整理五種常見的this錯誤指向的例子
2.1改變函數引用
eg: var obj = { name:'admin', show:function(){ console.log(this.name); } } var newShow = obj.show; newShow(); //this指向了window,函數的執行對象變成了window
2.2函數傳參
eg: var name='window'; var obj = { name: 'obj', show: function(){ console.log(this.name); } } function trigger(fn){ fn(); } trigger(obj.show); //this指向window
2.3:定時器傳參
var name='window'; var obj = { name: 'obj', show: function(){ console.log(this.name); } } setTimeout(obj.show,1000); //this指向了window
2.4:DOM對象事件
var name = 'window'; var oHtml = document.documentElement; var obj = { name: 'obj', show: function(){ console.log(this.name); } } oHtml.name = 'DOM'; oHtml.onclick = obj.show; //this指向了window
2.5:arguments類數組改變this指向問題
tip:傳入過多的實參,多余的實參雖然沒有什么用,但也是保存在函數中了
var length = 10; function fn(){ console.log(this.length); } var obj = { length: 5, method: function(fn){ fn(); arguments[0](); } }; obj.method(fn,"111","222"); //打印結果為10,3 tip1: obj.method的value並不是一個可以直接直接執行的函數,通過obj.method並不能執行函數,
所以this指向的並不是obj,輸出的不是5,this指向的是function這個無名函數,他的執行對象直接是window,發生隱式丟失 但是arguments[0]();也會執行,因為傳入的第一個參數就是一個函數,同時傳進了兩個多余的實參,所以打印出的為3 tip2: 數組是很特殊的對象,他的索引值相當於是obj2對象中的屬性值。所以說數組,類數組也會改變this指向問題。
3:顯示執行
通過函數的bind或call或apply執行
tip:當發生隱式執行的時候,還希望能拿到指定的this,可以通過函數的一些方法,強行改變到指定的this
這里拿bind方法給大家做一下介紹
bind()方法會創建一個新函數,稱為綁定函數,當調用這個綁定函數時,綁定函數會以創建它時傳入bind()方法的第一個參數作為this,
傳入 bind() 方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。 tip:改變this的指向,簡單來說,可以讓沒有這個功能的對象,具有另一個對象的功能 當blind();有多個參數的時候,第一個參數表示this的指向,其他的參數會與原函數的參數一起放在新函數中 eg1: var a = { name:"admin" } var b = { name:"uesr", show:function(){ console.log(this.name); } } b.show(); var c = b.show.bind(a); c(); //此時的c能夠獲取到a里面的name,利用a強行將this指向了a
eg2: 常用方式,用來改變函數內計時器函數this的指向 for(var i=0;i<ali.length;i++){ ali[i].onclick = function(){ setTimeout(function(){ console.log(this) }.bind(this),500) } } //不用blind()方法,this直接指向的是window,強行給計時器函數加了blind()方法,這時候誰觸發了函數的執行,this就指向了誰。