Javascript This 機制

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

相關文章
相關標籤/搜索