關於js中的this指向問題

每一個函數的this是在函數執行時綁定的,徹底取決於函數的調用位置(函數執行時地方)。 我把js中的this指向分爲如下5大類數組

默認綁定

默認綁定時是把this綁定在window上; 若是使用嚴格模式,則會綁定到undefined上bash

function foo(){
	console.log(this.a)
}
var a = 2
foo() // 2

複製代碼

這裏的this就綁定在window上,若是使用嚴格模式,則this指向的是undefinedapp

function foo(){
	'use strict'
	console.log(this.a)  // typeError:this is undefined
}
var a = 2
foo() // 2

複製代碼

隱式綁定

隱式綁定指的是在調用的位置是否有上下文關係(是否被某個對象所包含),這種狀況下誰調用指向誰函數

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

var obj = {
    a:2,
    foo: foo
}

obj.foo()  // 2 
// 因爲調用者是obj這個對象,因此foo中的this.a指向obj.a
複製代碼

一個多級對象在調用方法時,this綁定在離他最近的那個對象上ui

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

var obj = {
    a:2,
    foo: foo
}

var obj1 = {
    a:3,
    obj:obj
}

obj1.obj.foo() // 2
複製代碼

此外,隱式綁定有一種特殊狀況,就是隱式丟失 當並非直接調用某個函數或方法時,這時候會出現this綁定丟失的狀況。 如下是幾種綁定丟失的狀況this

  1. 給函數起別名
function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

var baz = obj.foo

var a = 'baz'
baz() // baz

// baz函數實際上引用的是foo函數自己,所以這時候使用了默認綁定
複製代碼
  1. 函數做爲另外一個函數的回調
function foo(){
    console.log(this.a)
}

var obj = {
    a:2,
    foo: foo
}

function doFoo(fn){
    fn()
}
var a = 'baz'
doFoo(obj.foo)  // baz
複製代碼

顯式綁定

顯示綁定是指經過call/apply/bind綁定的this。spa

他們的區別主要以下:prototype

  • call: 第一個參數是被綁定的this對象,以後依次寫要傳的函數參數
  • apply: 第一個參數是被綁定的this對象,以後是一個數組,須要的參數傳入這個數組
  • bind:bind返回的是一個函數,須要加()再次執行

new綁定(構造函數綁定)

經過 new 構造的函數實例,this綁定在當前實例上code

function Foo(a){
    this.a = a
}

var foo = new Foo(2)
console.log(foo.a) // 2
複製代碼

關於構造函數new的過程,主要分爲如下四步: 1.建立一個對象 2.構造這個對象的prototype等屬性 3.將這個對象綁定到this 4.返回這個對象對象

箭頭函數中的this

箭頭函數沒有本身的 this,當在內部使用了 this時,它會指向最近一層做用域內的 this,箭頭函數的this在定義時就肯定了。

var name = 'xiaohong';
var obj = {
    name: 'xm',
    sayName: () => {
        console.log(this.name) 
    }
}
obj.sayName() // xiaohong
複製代碼

此時的箭頭函數和sayName是同級的,它屬於obj,因爲箭頭函數沒有this,因此它的this指向離它最近的做用域的this,即指向window。

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
            console.log(this.name);
        }
    }
}
obj.sayName()()          //xm
複製代碼

因爲箭頭函數沒有本身的 this,當在內部使用了 this時,它會指向最近一層做用域內的 this,箭頭函數的最近一層的做用域爲obj內,因此它的this指向obj

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
          return () => {
            return () => {
              console.log(this.name);
            };
          };
       };
    }
}
obj.sayName()()()() // xm
複製代碼

以上函數定義了三個箭頭函數,因爲三個箭頭函數都不存在this,因此它的this指向了離箭頭函數最近的obj.

相關文章
相關標籤/搜索