js的this講解

涉及面試題:如何正確判斷 this?箭頭函數的 this 是什麼?先記住了一句話

this取什麼值是在函數執行時候確定的,而不是在函數定義時候確定的!

場景一:作爲普通函數

function foo(){
    console.log(this)
}
foo()

對於直接調用 foo 來說,不管 foo 函數被放在了什麼地方,this 一定是 window

場景二:作爲對象去調用:

const obj = {
  a: 2,
  foo: foo
}
obj.foo()

對於 obj.foo() 來說,我們只需要記住,誰調用了函數,誰就是 this,所以在這個場景下 foo函數中的 this 就是 obj 對象

注意setTimeout的用法

ES5:ES5中setTimeout的函數時作爲回調函數調用的,是掛載到window上的,所以this是指向window的。

const zhangsan = {
  name: '張三',
  sayHi() {
    console.log(this)
  },
  wait() {
    setTimeout(function(){
      // this === window
      console.log(this)
    }, 100)
  }
}

ES6:ES6中的箭頭函數自身是沒有作用域的,他的作用域來源它的上一級。

const zhangsan = {
  name: '張三',
  sayHi() {
    console.log(this)
  },
  wait() {
    setTimeout(() => {
      // 這個this是指向zhangsan這個對象的
      console.log(this)
    }, 100);
  }
}

場景三:作爲對象實例調用

const c = new foo()

對於 new 的方式來說,this 被永遠綁定在了 c 上面,不會被任何方式改變 this

場景四:作爲call apply bind

fn.call({ x: 100 }) //this指向{ x : 100 }

const f2 = fn.bind({ x:200 })
f2() // this指向{x: 200}

 bind會更改this的指向,如果有多個bind鏈式調用的話,this也只是指向bind的第一個中對象。

場景五:箭頭函數中的 this

function a() {
  return () => {
    return () => {
      console.log(this)
    }
  }
}
console.log(a()()())

首先箭頭函數其實是沒有 this 的,箭頭函數中的 this 只取決包裹箭頭函數的第一個普通函數的 this。在這個例子中,因爲包裹箭頭函數的第一個普通函數是 a,所以此時的 this 是 window另外對箭頭函數使用 bind 這類函數是無效的

this的優先級:

new 的方式優先級最高,接下來是 bind 這些函數,然後是 obj.foo() 這種調用方式,最後是 foo 這種調用方式,同時,箭頭函數的 this 一旦被綁定,就不會再被任何方式所改變。

看一個例子:

      var name = 'global'
      var obj = {
        name: 'local',
        foo: function(){
          this.name = 'foo';
        }.bind(window)
      }
      var bar = new obj.foo();
      setTimeout(function(){
        console.log(window.name)
      }, 0);
      console.log(bar.name)//因爲bar的優先級高於bind,所以this並不會指向window
      var bar3 = bar2 = bar;
      bar2.name = 'foo2';
      console.log(bar3.name)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章