0%

JS 核心觀念筆記 - this 簡單呼叫 Simple Call

this

Simple Call 簡易呼叫

下方這個方式就是 this 的簡易呼叫,但請盡量不要使用簡易呼叫的 this。

1
2
3
4
5
6
var vm = "全域";

function callName() {
console.log(this.vm);
}
callName();

最簡單判斷是不是 Simple Call 的方式就是看到直接呼叫函式這個方法(如上方程式碼範例)。

以下為 Simple Call 的情境

IIFE 立即函式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var vm = "全域";

function callName() {
console.log(this.vm);
}

//IIFE
(function () {
console.log(this.vm); //全域

function callSomeone() {
console.log(this.vm); //全域
}
callSomeone();
})();
  • 立即函式是定義後就會直接執行,這邊並沒有另外定義一個變數給立即函式,所以他會找到外層的全域變數。
  • 立即函式有再定義一個函式並直接呼叫他,因為前面也沒有給予定義的變數或物件,所以它也會直接找到外層的變數並使用它。
  • 通常全域變數的會定義在 window 這個全域物件下,但 Simple Call 並不是 window.simpleCall() 這個概念下被呼叫。
  • 不是看呼叫的位置,而是呼叫的方式來決定 this 指向的是誰。

閉包 Closure

閉包的概念是在函式內再宣告一個函式,並使其內部函式去調用外層函式內的變數。

1
2
3
4
5
6
7
8
9
10
11
12
var vm = "全域";

function easyCard(base) {
var money = base;
var card = "悠遊卡";
return function (update) {
money = money + update;
console.log(this.vm, money); //全域 110
};
}
var myEasyCard = easyCard(100);
myEasyCard(10);

Callback

就是把 A 函式傳到 B 函式內,並在 B 函式內執行,執行後會指向全域的變數。

1
2
3
4
5
6
7
8
9
10
var vm = "全域";

function myEasyCard(callback) {
var money = 100;
return callback(money);
}

myEasyCard(function (money) {
console.log(this.vm, money + 100); //全域 200
});

forEach

下方有一陣列,取得資料可用 forEach 相當方便,forEach 也是一個 callback function,this 也會指向全域的變數,而 i 會取得陣列中的資料。

1
2
3
4
5
6
var vm = "全域";

var a = [1, 2, 3];
a.forEach(function (i) {
console.log(this.vm, i); // 全域 1,全域 2,全域 3
});

函式中直接定義 this

  • 下方有一個物件裡面有一個 callName 的函式,當中在執行 setTimeout 的函式,而這個 SetTimeout 函式屬於 callback function,this 會指向全域變數。
  • 因為其呼叫方式的是直接在全域下呼叫,所以不管所定義的位置在哪裡,都會指向全域。
1
2
3
4
5
6
7
8
9
10
11
var vm = "全域";

var family = {
vm: "小明",
callName: function () {
setTimeout(function () {
console.log(this.vm); //全域
}, 1000);
},
};
family.callName();

如果想要取得物件 family 物件中的變數可以在裡面直接定義 this,如下方程式碼。

1
2
3
4
5
6
7
8
9
10
11
12
var vm = "全域";

var family = {
vm: "小明",
callName: function () {
var self = this; //定義 this
setTimeout(function () {
console.log(self.vm); //將原本的 this 改為 Self,得到 小明
}, 1000);
},
};
family.callName();

資料參考

  1. 鐵人賽:JavaScript 的 this 到底是誰?
  2. JavaScript This 系列文:this 為什麼指向 window
  3. JavaScript This 系列文:this 與物件的關係
  4. 重新認識 JavaScript: Day 20 What’s “THIS” in JavaScript (鐵人精華版)
  5. 你懂 JavaScript 嗎?#15 閉包(Closure)