Vue.js 从零开始:This 是什麽?

学习JavaScript也有一阵子,当有人问起This是什麽,都无法解释的很清楚,代表理解的不够彻底,今天来复习This的指向,是进入Vue之前,必须掌握的观念之一。


影响 This 的是在於函式的呼叫方法,并非宣告的时机,以下的程序码来理解这句话的意思,这边用var来示范。

var demo = '全域变数';
function callDemo() {
  console.log(this.demo);
}
var obj = {
  demo: '物件',
  callDemo(){
    console.log(this.demo);
  }
}
callDemo();

console.log的结果是




全域变数,This的指向关键在於如何呼叫他,注意呼叫函式前一个的”物件“,约有九成的This是这样指向,
接下来我们把CallDemo()前面加个物件。

var demo = '全域变数';
function callDemo() {
  console.log(this.demo);
}
var obj = {
  demo: '物件',
  callDemo(){
    console.log(this.demo);
  }
}
obj.callDemo();

console.log的结果是



物件,由这点来证明This的指向是跟呼叫方式有关系,再来几个例子。

var demo = '全域变数';
function callDemo() {
  console.log(this.demo);
}

var warpobj = {
  demo: '外层物件',
  callDemo,
  innerObj: {
    demo: '内层物件',
    callDemo,
  }
}
warpobj.callDemo();

callDemo()前面的物件是warpobj,console.log结果当然是外层物件,再来一个陷阱题。

var demo = '全域变数';
function callDemo() {
  console.log(this.demo);
}

var warpobj = {
  demo: '外层物件',
  callDemo,
  innerObj: {
    demo: '内层物件',
    callDemo,
  }
}
warpobj.innerObj.callDemo();

console.log结果是




内层物件,注意呼叫函式前一个的”物件“不用管innerOnj前面的物件。

var demo = '全域变数';
function callDemo() {
  console.log(this.demo);
}
var obj2 = {
  demo: '物件2',
  fu() {
    callDemo();
  }
}
obj2.fu();

console.log结果是全域,原因是callDemo()前面并没有物件,所以This指向变成全域。

最後一个范例:

var demo = '全域变数';
function callDemo() {
  var demo = "测试"
  console.log(this.demo);
}
var obj4 = {
  demo: '物件2',
  fu() {
    setTimeout(function() {
      console.log(this.demo);
    },100)
  }
}
obj4.fu();

结果是全域,Callback function大部分的This都是指向全域,只有少部分会重新定义,要避免指向跑向全域有两种解法。

  1. vm
  2. array function

第一种解法:

var demo = '全域变数';
function callDemo() {
  var demo = "测试"
  console.log(this.demo);
}
var obj4 = {
  demo: '物件2',
  fu() {
    const vm = this
    setTimeout(function() {
      console.log(vm.demo);
    },100)
  }
}
obj4.fu();

将This指向变数vm,让他指向固定住。

第二种解法:

var demo = '全域变数';
function callDemo() {
  var demo = "测试"
  console.log(this.demo);
}
var obj4 = {
  demo: '物件2',
  fu() {
    const vm = this
    setTimeout(() => {
      console.log(vm.demo);
    },100)
  }
}
obj4.fu();

把setTimeout改成箭头函式,因为箭头函式没有自己的This,所以This会外层的函式找就是fu(),结果跟第一个解法ㄧ样都会是'物件2'。


补充说明

Execution Context(Global)
https://ithelp.ithome.com.tw/upload/images/20210920/20118347GeMne8eQYT.png
不论何时执行JavaScript程序,都会是在执行环境内执行,我们常用的浏览器Browser,执行环境(Execution Context)就是你的全域执行环境(Global),Global创造了两件事,创造了全域物件(Global Object)和特殊变数This,你还没写程序的时候,就已经有这两个东西的存在,当你在开发者工具的console输入windowc或This,会跳出长长一串的内容:
https://ithelp.ithome.com.tw/upload/images/20210920/20118347E3iIEkvCiy.png
之後再补上这段JavaScript:

var a = 'hello world!!';
function b(){

};

开发者工具就会出现我们输入的JavaScript:
https://ithelp.ithome.com.tw/upload/images/20210920/20118347o7sWqDkrYP.png
或是直接输入this.a或是windows.a都会有'hello world!!'的结果,代表Global Object也是一个window物件,全域情况下window也等於this,this参照window物件,但前提是执行环境要在浏览器Browser执行,如果是Node那情况就会不同。

参考资料


卡斯柏
重新认识 JavaScript
克服JS的奇怪部分 2-10


<<:  【程序】职场上的那些刻板印象 转生成恶役菜鸟工程师避免 Bad End 的 30 件事 - 6

>>:  Day 19 ( 中级 ) 阵列点灯 ( 动画 )

【Android-Span】 设置TextView特定位置颜色+插入图片!

Span可以做到的事情有很多,如 -更改特定位置的字体颜色/大小 -新增项目符号 -可点击 -换行等...

Day20:终於要进去新手村了-Javascript-函式-建立函式

终於来到函式的基础,建立函式了,以下就是基本的语法架构: function 函式名称(这个位置用来呼...

【Laravel 】虚拟主机配置

一. 【文件】- host文件 【位址】- WINDOWS\system32\drivers\etc...

杂七杂八问题篇

倒数第二篇~ 来个不分类的杂七杂八问题篇, 有些问题,不知道该怎麽分类, 而有些分类,这次没机会写到...

HTTP标头开发方法

用於检查网站的当前标头。 标头按重要性顺序列出,但是请注意,除非从头开始设计应用程序,否则很难实施适...