this指向

es5 this指向分四種狀況

狀況一:純粹的函數調用
  • 這是函數的最一般用法,屬於全局性調用,所以this就表明全局對象。
var x = 1;
function test() {
   console.log(this.x);
}
test();  // 1
複製代碼
狀況二:做爲對象方法的調用
  • 函數還能夠做爲某個對象的方法調用,這時this就指這個上級對象。
function test() {
  console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test;

// 相似這種寫法
 var obj = {
    x:"1",
    m: function() {
        console.log(this.x);
    }
}
console.log(obj.m())

obj.m(); // 1
複製代碼
狀況三 做爲構造函數調用
  • 所謂構造函數,就是經過這個函數,能夠生成一個新對象。這時,this就指這個新對象。
function test() {
  this.x = 1;
}

var obj = new test();
obj.x // 1
複製代碼
  • 運行結果爲1。爲了代表這時this不是全局對象,咱們對代碼作一些改變:
var x = 2;
function test() {
  this.x = 1;
}

var obj = new test();
obj.x  // 1

複製代碼
  • 運行結果爲1,代表全局變量x的值根本沒變。
狀況四 apply,call,bind 調用
  • apply
var a = {
        name : "Cherry",
        func1: function () {
            console.log(this.name)
        },
        func2: function () {
            setTimeout(  function () {
                this.func1()
            }.apply(a),100);
        }
    };

    a.func2()            // Cherry
複製代碼
  • call
var a = {
        name : "Cherry",
        func1: function () {
            console.log(this.name)
        },
        func2: function () {
            setTimeout(function () {
                this.func1()
            }.call(a),100);
        }
    };

    a.func2()            // Cherry
複製代碼
  • bind
var a = {
        name : "Cherry",
        func1: function () {
            console.log(this.name)
        },
        func2: function () {
            setTimeout(  function () {
                this.func1()
            }.bind(a)(),100);
        }
    };

    a.func2()            // Cherry
複製代碼

箭頭函數和普通函數區別

* 沒有 this,不能改變 this 綁定
* 不能經過 new 調用,固然也沒有原型(prototype)
* 沒有 arguments 對象,不能有相同命名參數
* 箭頭函數雖然沒有 this ,可是仍是能夠在內部使用 this 的
* this 的綁定取決於定義函數時的上下文環境
* 一旦函數調用,任何改變 this 的方法都無效
複製代碼

練習題

let x = 11111
let a = {
    x: 1,
    init() {
        // 箭頭函數的 this 取決於 init,因此能夠打印出 1
        document.addEventListener('click', () => console.log(this.x))
    },
    allowInit: () => {
        // allowInit 直接是個箭頭函數,因此這時的 this 變成了 window
        // 可是並不會打印出 11111,使用 let 時變量也會被提高至塊級做用域的頂部,可是隻提高聲明,不提高初始化
        console.log(this.x)
    },
    otherInit() {
        // 普通函數的 this 取決於調用函數的位置,this 指向 document
        // 若是想打印出 x,可使用 bind
        document.addEventListener('click', function() {
            console.log(this.x)
        })
    }
}
a.init() // -> 1
a.allowInit() // -> undefined
a.otherInit() // -> undefined
複製代碼
相關文章
相關標籤/搜索