这篇文章要来介绍 this
终于进入重头戏之一了喔!
this
也是让很多开发者头痛的地方喔,这篇文章会用简单的方式让大家知道,this 现在到底是谁!
那我们开始吧~
var myName = '真心镇大冒险';function callName () {}callName();
我们先这样执行以后呢,打开 chrome 的开发者人员工具,然后选择 Source 的 Tag,按下这个暂停的按钮
重新整理之后呢,我们来进入这个函式的执行堆叠~
接着我们进入这个函式的执行堆叠之后,你就会发现 this
居然一开始就存在了
也就是说就算不做任何事,只要函式的作用域一创建,就会有 this
这个变数。
而现在图片中的例子呢,this
是指向全域的物件 window。
而这个 this
的指向规则,跟我们怎么去呼叫这个函式呢有很大的关联性。
我们先稍微调整一下程式码~
var myName = '真心镇大冒险';function callName () { console.log(this.myName);}callName();
重新整理执行后就会得出 真心镇大冒险
所以透过上方的例子你只需要了解到两件事
this 是 function 被执行的时候自带的变数this的指向跟函式的呼叫有关只要好好了解这篇文章的内容呢,有8成以上的this的指向你都能够掌握
接下来就要来解释第二点~
那么 this
呢,是我们在执行函式的时候它自然就会产生。它不需要特别的去宣告它,就是一个保留的关键字。
不管是在全域的环境下,还是特定的函式中,你都可以直接调用 this
。
因为 this
在每个执行环境都会存在,所以很多人会误认为 this
就是指向函式本身。
其实函式本身能够提供的属性有限,那通常来说我们并不会使用 this
去调用函是本身。
而 this
通常是指向一个可以被调用的物件,所以大家不要误认为 this
就是指向函式本身。
那么我们刚刚就有说到,this
的指向跟函式的呼叫有关
那么会影响 this
的调用方式都列在下面这张图中:
this
有 8 成都是运用到这个观念。简易呼叫: 这个是最常见的函式呼叫方式,但是要注意,简易呼叫不建议用运用它的 this
。 在这篇文章中也会介绍甚么是简易呼叫?以及为什么要避免运用简易呼叫的 this
。bind apply call: 则是绑定函式到特定的 this
的方法。new: 建构式的运算子,我们之后会在原形的章节介绍到。DOM 事件处理器: 陆续会介绍到。箭头函式(ES6): 陆续会介绍到。那么 this
到底有甚么用呢?
也就是可以透过 this
指向前面的物件。
而这边要介绍,其实物件的方法调用是最常见的形式,这边也是要记住两个重点:
也就是说使用物件的方式调用的时候,你只需要关注它是在哪个物件下调用的就好!
以下面的例子来说:
基本上这样执行函式的时候,后面的函式的 this
就是指向前面这个物件。
就这么简单,你只要掌握了这个原则就掌握了八成喔! 可喜可贺可喜可贺~
接下来呢我们来看一下範例~
範例1
var myName = '真心镇大冒险';function callName () { console.log(this.myName);} var family = { myName: '小明家', callName: callName}family.callName();
好,在这里我们不管 callName
这个函式是怎么定义的,我们只 care 它是在哪个物件下被呼叫。
因此这个 this
现在就是指向 family 这个物件。
所以很明显透过 callName的函式印出来的结果应该是 '小明家'
也可以多修改一下程式码,看看 this
现在是指向谁
var myName = '真心镇大冒险';function callName () { console.log(this, this.myName);} var family = { myName: '小明家', callName: callName}family.callName();
範例2
var myName = '真心镇大冒险';function callName () { console.log(this, this.myName);}var family = { myName: '小明家', callName: callName, Ming: { myName: '小明', callName: callName, }}family.callName();family.Ming.callName();
很明显 family.callName();
跟刚刚一样就会印出小明家,但第二个 family.Ming.callName();
这个 this
指向的就是 Ming 这个物件,所以印出来的就会是小明。
範例3
var myName = '真心镇大冒险';function callName () { console.log(this.myName);}var family = { myName: '小明家', callName: function () { console.log(this.myName); }}family.callName(); // 小明家var callName = family.callName;callName(); // ?
那么这边我们可以看到 family.callName();
这段的逻辑就是跟上面一样, this
指向 family 的物件。
那么如果我们今天把 family.callName
重新命名一个变数,然后在执行这个变数的话?
现在 this
会指向谁呢?
执行的结果就是 '真心镇大冒险'
为什么会这样呢?
因为它被执行在全域的情况下,它的 this
就指向到了 window 的物件,所以它 console.log 出来的结果就会是 '真心镇大冒险'喔!
这个篇文章就先解说到这里,希望对各位有帮助! 汪汪~