1.2.3.8.物件、函數與「this」

  • 當函數被呼叫時 (函數物件中的CODE property被執行), 會創造新的執行環境, 放到執行堆中

  • 如同前述的範圍鏈, 當執行環境被建立時會產生幾樣東西:

    • 1.變數環境 (Variable environment), 外部環境 (Outer environment)

      • 當在變數環境找不到變數時, 會到所參照的外部環境去尋找

    • 2.this

      • 不須宣告, 由JavaScript engine產生, this依據函數的呼叫方式會指向不同的物件

    • 3.外部參照的環境

  • this

    • 1.函數中的this會指向全域物件

    • 2.函數表達式中的this會指向全域物件

    • 3.物件實體 (object literals)的方法中的this會指向物件實體

    • 4.(坑) 物件實體 (object literals)的方法中的方法的this會指向全域物件

      • 物件實體 (object literals)的方法中的任何方法都有問題

      • 解法: var self = this;

//印出Window (指向全域物件)
console.log(this)

//呼叫a, 表示執行CODE property: 建立執行環境與this
//印出Window (指向全域物件)
function a(){
console.log(this)
//為全域物件增加屬性
this.newvvariable = 'hello';
}

a();

//函數表達式
var b = function(){
console.log(this)
}

//印出Window (指向全域物件)
b();

//呼叫hello
console.log(newvvariable);

//物件實體 (object literals)
var c = {
    name: 'The c object'
    log: function(){
        console.log(this)
    }
}

//印出Object {name: "The c object", Log: function}
c.log();

var c = {
    name: 'The c object'
    log: function(){
    this.name = 'Update c object'
        console.log(this)
    }
}

//印出Object {name: "Update c object", Log: function}
c.log();

var c = {
    name: 'The c object'
    log: function(){
        this.name = 'Update c object'
        console.log(this)

        //函數表達式: 預期會改變c的name
        var setname = function(newname){
            this.name = newname;
        }

        setname('Update again! The c object');
        console.log(this);
    }
}

//印出:
//Object {name: "Update c object", Log: function}
//Object {name: "Update c object", Log: function}
//setname沒有做任何事!
//但是全域物件中的name會被setname改變
c.log();

var c = {
    name: 'The c object'
    log: function(){
        //this會指向c
        //self, this都指向同一個記憶體位置
        var self = this;

        //將所有要用this的地方都改成self
        self.name = 'Update c object'
        console.log(self)

        //函數表達式: 預期會改變c的name
        var setname = function(newname){
            //當函數裡沒有self變數時, 會往上一層找到self
            self.name = newname;
        }

        setname('Update again! The c object');
        console.log(self);
    }
}

//印出:
//Object {name: "Update again! The c object", Log: function}
c.log();

Last updated

Was this helpful?