兩年前,曾經的組長對我說過,一個前端連閉包原型this都搞不明白,還好意思說本身是前端。以後我一直去試着理解this,看了好多博客和視頻教學,發現好像並非特別好理解。可是在以後的項目中,我都使用了this。在接觸和使用事後,好像對this有點了解,特別寫一篇博客記錄一下關於this的二三事,方便之後查詢,也給剛剛接觸前端的小夥伴一點點幫助前端
首先this在js中理解起來很簡單,他就是當前對象,也能夠理解成指向的對象,那麼問題來了,那麼我怎麼知道當前指的是那個對象?bash
首先咱們想理解this的話,咱們必需要理解兩句話
全局變量是window的屬性,函數是window的方法
this誰最後調用,他就是誰閉包
首先咱們理解一下使用代碼理解一下app
let a = '5'
console.log(window.a) //5
function foo(){
reutrn 'foo'
}
console.log(window.foo()) //foo
複製代碼
咱們申明瞭一個全局變量a和一個函數foo,可是咱們調用他們的時候並無直接調用,而是使用window這個全局對象調用來調用屬性和方法的方式調用,因此能夠看到打印出他們的值,能夠得出全局變量是window的屬性,函數是window的方法這一結論 而後咱們運行代碼函數
var name = 'Tom'
function name(){
var name = 'Jerry'
console.log(this.a)
}
name() // 'Tom'
console.log(this) //window
複製代碼
在全局做用域中,函數是window的方法,name函數由window調用,那麼函數內部的this指向的就是window,固然打印出出的this.name固然就是全局做用域下的name值了 簡單瞭解了this的指向,咱們細分一下幾個複雜場景下面的this指向(this究竟是誰)學習
var name = 'apple'
function fn0(){
var name = 'Tom'
function fn1(){
console.log(this.name);
}
fn1();
}
fn0();
複製代碼
函數內部嵌套的內部函數,依然指向全局對象(window)ui
function Person(name){
this.name = name;
this.say = function(){
console.log('Hello'+this.name)
}
}
Person.prototype.printName = function(){
console.log(this.name);
};
var a = new Person('Byron');
a.say() //"HelloByron"
a.printName() //"Byron"
複製代碼
在構造函數中,this的指向就調用他這個對象的方法,不管是否在原型上this
var name = 'apple'
var obj1 = {
name: 'Byron',
fn : function(){
console.log(this.name);
}
};
obj1.fn() // Byron
複製代碼
在對象中使用也是同樣,this的指向在就是他調用他這個對象上 這裏有個小陷阱,加上代碼看一下spa
var fn2 = obj1.fn;
fn2(); //'apple'
複製代碼
咱們把方法賦值給一個變量,直接用變量調用看看,這個時候咱們就能夠看出來,this的指向改變了,變成全局的了,符合咱們上面的第二句話,this誰最後調用,他就是誰prototype
在setTimeout、setInterval的內部函數中,不管是誰調用,他指向的都是全局變量
var name = 'apple'
var obj1 = {
name: 'Byron',
fn : function(){
setTimeout(function(){
console.log(this.name)
},300)
setInterval(function(){
console.log(this.name+'666')
},300)
}
};
ob1.fn() //apple
//apple+666
fn1 = obj1.fn
fn1() //apple
//apple+666
複製代碼
能夠看得出來,打印的結果能夠得出this指向的都是全局對象window
document.querySelector('input') = function(){
console.log(this.value)
}
複製代碼
DOM對象綁定事件中的函數中的this指向的是當前這個DOM節點
箭頭函數中,this的指向有點特別:建立時的封閉詞法上下文的this保持一致
var name = 'tom'
var obj1 = {
name : 'Byron',
fn :function(){
setTimeout(()=>{
console.log(this.name)
},0)
}
};
obj1.fn() //'Byron'
複製代碼
因爲箭頭函數特殊的緣由,箭頭函數沒有原型,因此箭頭函數自己沒有this,他只能指向定義外層第一個普通的this,那若是那個普通的this變化了,箭頭函數中的this會指向哪呢?
var name = 'tom'
var obj1 = {
name : 'Byron',
fn :function(){
setTimeout(()=>{
console.log(this.name)
},0)
}
};
var obj2 = {
name : 'hello world'
}
obj1.fn.call(obj2) //'hello world'
複製代碼
能夠看出若是外層的this變化了,箭頭函數內的this會隨着外層的變化而變化
1.this的指向不是固定的,是會變化的(這篇博客尚未講call,apply,bind等函數的用法)
2.this誰調用他,他就指向誰
3.在setTimeout、setInterval中,不使用箭頭函數的狀況下this指向全局對象window
4.箭頭函數沒有原型,this指向外層做用域
複製代碼
想要完全瞭解this,必須在項目中多多使用this,遇到問題打印一下,結合網上的博客分析爲何會這樣,這樣學習起來也比較快,理解也能加深,畢竟學習一個東西的最好的方法就是去使用他。若是文中有錯誤,但願你們在評論裏面提出指正,本人加以改正