當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JS this详解
this的由來
javascript允許在函數體內,引用當前環境的其他變量
var fn=function(){console.log(x) }上面代碼使用變量x,而變量x由當前的運行環境提供。
那么問題來了,函數可以在不同的運行環境下執行,所以需要一種機制,可以在函數體內內部獲取當前的運行環境(context),所以this就出現了,它的作用就是在函數體內部,指代當前的運行環境。
this的幾種模式
在我理解下,this分為一下幾種情況:
下面我們針對這幾種情況,舉例說明,并說明原理。
方法調用模式
//聲明位置var fn=function(){console.log(this.x)} var x="2"var obj={x:"1",fn:fn}//調用位置obj.fn();//1//調用位置fn();//2以上代碼,可以看到,this指向調用它所在方法的對象,say方法在obj對象下,所以this指向obj,fn在window對象下,所以this指向window,也可以看出來,this和聲明位置無關,和調用位置有關。
函數調用模式
var x="2"//聲明位置var fn=function(){console.log(this.x)} //調用位置fn();//2匿名函數,setTimeout:
var that=this;(function(){console.log(this===that)//true})()setTimeout(() => {console.log(this===that)//true}, 0);?可以看出以上所有情況,this指向window
call,apply,bind模式下
var obj={name:'hty',getName:function(){console.log(this.name)}}var otherObj={name:'hml'}var name='upupup'obj.getName()//htyobj.getName.call();//upupupobj.getName.call(otherObj);//hmlobj.getName.apply();//upupupobj.getName.apply(otherObj);//hmlobj.getName.bind(this)();//upupupobj.getName.bind(otherObj)();//hml?可以看出,call,apply,bind的this指向第一個參數,如果有朋友不太明白,可以看下,我上篇寫的call,apply,bind的原理就明白了。
構造函數模式下
var flag=undefined; function Fn(){flag=this;} var obj=new Fn()console.log(flag==obj)其實,這個this指向obj,內部原理還是用apply把this指向obj的,在后續文章,我會寫一個關于new的原理,大家有興趣,可以關注下。
嚴格模式
"use strict";var fn=function(){return this} fn() ==undefined;//true可以看出,在嚴格模式下,fn是被直接調用的,并沒有沒有被執行環境所定義,也就是說不是作為對象的屬性或方法調用的(如window.fn())
箭頭函數
//聲明位置var fn = (()=>{console.log(this.x)}) var x="2"var obj={x:"1",fn:fn}//調用位置obj.fn();//2//調用位置fn();//2以上可以看出,箭頭函數在定義時就綁定了this,而非取決與調用位置了,同樣用call,apply,bind都無法更改this。
var globalObject = this;var foo = (() => this);console.log(foo() === globalObject); // truevar obj = {foo: foo};// 嘗試使用call來設定thisconsole.log(foo.call(obj) === globalObject); // true// 嘗試使用bind來設定thisfoo = foo.bind(obj);console.log(foo() === globalObject); // true總結
- 上一篇: 001_什么是网站
- 下一篇: 101113香港游有感