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?