这个章节要来介绍 简易呼叫(Simple Call)
var myName = '真心镇大冒险';function callName () { console.log(this, this.myName);}callName();
可以看到这是上一篇文章的範例,并且在这里 callName();
就是典型的 简易呼叫(Simple Call)。
并且要特别提醒!
尽可能不要使用 简易呼叫(Simple Call) 的 this
。
原因呢我们后面会提到,我们先接着看下面的範例:
var myName = '真心镇大冒险';function callName () { console.log(this, this.myName);}// IIFE(function () { console.log(this.myName); function callSomeone () { console.log(this.myName); } callSomeone();})();
首先我们利用一个立即函式包住 console.log(this.myName);
这里的这个 this.myName 因为没有在立即函式的内部定义,所以会指向外层的 真心镇大冒险。
然后我们在这个里面又订一个另外一个函式 callSomeone,并且立刻执行他。
所以在这里呢,callSomeone();
也是一个典型的 简易呼叫(Simple Call)。
所以这里的 this
也是指向全域的 window 物件。
在这边提醒大家~之前有提过一个概念就是
所谓的全域变数都是挂在 window 这个物件下,所以很多人会以为我们执行 简易呼叫(Simple Call) 的时候,会是 window.callSomeone()
的感觉。
但其实并不是这样的概念,下一篇文章会再详细说明这个部分。
简单来说重点就是
只要看到直接执行的呼叫句就是 简易呼叫(Simple Call)。window.callSomeone()
的执行方式并不是 简易呼叫(Simple Call)。简易呼叫(Simple Call)的 this
指向的全域的物件 window。了解了这些以后我们继续往下~
之前我们有讨论到闭包的状况,调用函式中回传的函式,也是属于 简易呼叫(Simple Call) 的一种。
var myName = '真心镇大冒险';function easyCard (base) { var money = base; var name = '悠游卡'; return function (update) { money = money + update; console.log(this.myName, money); }}var MingEasyCard = easyCard(100);MingEasyCard(10);
执行上述的程式码,可以看到 this.myName
的指向还是全域的 '真心镇大冒险'。
这边就得证 MingEasyCard(10);
也是 属于 简易呼叫(Simple Call) 的一种。
再来讨论 callBack 的状况
callback就是将一个函式传到另一个函式内,并且在另外一个函式内执行。
那么,再另一个函式里面执行的形式,也是属于 简易呼叫(Simple Call) 喔!
那么一样这边的 this
指向的就是全域 window。
var myName = '真心镇大冒险';function myEasyCard (callback) { var money = 100; return callback(money);}myEasyCard(function (money) { console.log(this.myName, money + 100);});
所以结果印出来就会是 真心镇大冒险 200
除了我们这边写的这个之外呢,还有就是 forEach 的例子
var myName = '真心镇大冒险';var a = [1, 2, 3];a.forEach(function (i) { console.log(this.myName, i);});
这样执行了以后呢,会得到下面的结果:
所以 callback function 也是属于 简易呼叫(Simple Call) 喔!
其 this 的指向会指向到 window 物件。
再来就是最后一个範例:
var myName = '真心镇大冒险';var family = { myName: '小明家', callName: function () { setTimeout(function () { console.log(this.myName); }, 1000); }}family.callName();
请问这样console.log印出来会是 真心镇大冒险 还是 小明家 呢?
答案如上,印出来是 真心镇大冒险。
原因是因为,虽然执行的方式是在 family 下执行,的确callName里面执行环境的指向是family的物件。
但是在那裏面又包了一个setTimeout的执行环境,传入的是 callback function,所以 callback function 里面的 this 指向就还是全域的 window物件。
所以答案就是 真心镇大冒险喔!
但是,如果我今天就是要取得family这个物件里面的 myName,也就是 小明家 的话,我该怎么做呢?
很简单,只需要先在 callName的执行环境中,把this保存再某一个变数里面,并且替换 this => 变数名称 就可以了喔!
程式码如下:
var myName = '真心镇大冒险';var family = { myName: '小明家', callName: function () { var self = this; setTimeout(function () { console.log(self.myName); }, 1000); }}family.callName();
这样子执行的结果就会印出小明家了
其中乘载 this 的变数名称通常会被叫做 self、vm、that等,依据不同的开发环境会有不同的命名习惯。
好~那么这篇文章主要就是介绍 简易呼叫(Simple Call),如果没有问题的话,我们就继续往下一篇文章迈进吧!