js中除了聲明定義的形參以外,每一個函數還能夠接收兩個附加參數(this、arguments)。這裏咱們就來仔細學習一下this吧。javascript
在javascript中明確this指向大體有四種狀況java
函數調用的模式
,this
指向window
function aa() { console.log(this); } aa(); // window
方法調用模式
, this指向方法所在的對象
var a = {}; a.name = 'zjj'; a.getName = function(){ console.log(this.name); } a.getName(); // 'zjj',這裏this指向的是調用的那個對象
構造函數模式
, this指向新生成的實例
function aaa(name){ this.name = name; this.getName = function(){ console.log(this.name); // 這裏的this指向實例化的對象 } } var a = new aaa('meils'); a.getName(); // 'meils' var b = new aaa('bobo'); b.getName() // 'bobo'
apply/call調用模式
var list1 = {name: 'zjj'}; var list2 = {name: 'lll'}; function a(){ console.log(this.name); } a.call(list1); // 'zjj' a.call(list2); // 'lll'
先來一個面試題吧es6
obj = { name: 'a', getName : function () { console.log(this.name);console.log(this); } } var fn = obj.getName obj.getName() // 這裏this指向的是調用getName的那個對象 var fn2 = obj.getName() // 同上執行一次 ,返回的fn2已經不是一個函數了 fn() // 這裏的this指向的是window,因爲window下並無name變量,因此沒有輸出 fn2() // 因爲fn2不是一個函數,所以會報錯 // 輸出以下 a {name: "a", getName: ƒ} a {name: "a", getName: ƒ}getName: ƒ ()name: "a"__proto__: Object Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} Uncaught TypeError: fn2 is not a function
下面咱們依舊經過例子來學習this哦
實例一面試
function demo1(){ console.log(this) } function demo2(){ this.num=2 function demo3(){ this.num++ console.log(num) } return demo3; } demo1(); // this指向window var a = demo2(); // a(); // 3 a變量將demo2函數執行後的的返回值及demo3函數返回, 而後執行,此時this依舊指向window
var obj1={ value:3, increment:function(){ this.value++; console.log(this,this.value) } } obj1.increment() // {value: 4, increment: ƒ} 4
實例二app
var obj2={ value:4, increment:function(){ this.value++; console.log(this,this.value); (function(){ console.log('這又是啥',this,this.value) this.value=1 })() }, print:function(){ console.log('print',this.value) } } obj2.increment() // this是obj2 obj2.print() var P=obj2.print P() // this是window // {value: 5, increment: ƒ, print: ƒ} 5 這又是啥 Window undefined print 5 print 1
obj2.increment() this是obj2,執行了value++,此時的value爲5,然後是一個自我執行的函數,這裏的this是window,因爲window下的value尚未申明,所以返回的是undefined。以後執行obj2.print()這裏的this是obj2,輸出value是5,然後變量P執行了obj2的print方法,這裏的this指向了window,因此輸出的是1
ES6的箭頭函數
如今咱們都常常會用的es6的箭頭函數,箭頭函數是不會自動綁定this的,默認從上一級繼承下來,那不妨把剛纔的例子改下看看函數
var obj1={ value:3, increment:()=>{ this.value++; console.log(this,this.value) } } obj1.increment() // 這時候會看到輸出window對象和一個NaN
如前面所說箭頭函數不會自動綁定this,因此執行increment函數中的this依舊會指向window,而window下的value還不存在,因此爲undefined再執行+1操做因此value就變成了NaN了
var obj2={ value:4, increment:()=>{ this.value++; console.log(this,this.value); (function(){ console.log('這又是啥',this,this.value) this.value=1 })() }, print:()=>{ console.log('print',this.value) } } obj2.increment() obj2.print() var P=obj2.print P() // 打印結果出以下 // Window // NaN // 這又是啥 Window // NaN // print 1 // print 1
第一個依舊window對象(this沒綁定的嘛),後面的value固然又是沒聲明.....而後自執行函數也沒得說,後面才接着給window的value賦值爲1了,後面就兩句天然輸出兩次1了相信看了上面的例子,你們必定對this的使用有了必定的瞭解了吧。加油,多看幾遍,影像會更深的呢post