「this」好七怪!

听前辈说,「this」在JavaScript里面是一个大坑。

前面有提过「this」在事件监听中,不考虑事件冒泡的情况下,this就等同是e.target,但是如果是被事件冒泡触发的this则为e.currentTarget。

现在来谈谈「this」在其他地方要注意的事情。

首先要记住这句话,只要理解这个原则,大部分遇到「this」的状况都可以轻松掌握:

「this代表的是function执行时所属的物件,而不是function本身」

「this」是在函式被呼叫的时候被自动生成的内部物件,this不等於function,随着呼叫函示的物件不同,「this」所指向的值也不同。

没有特别指定this的情况下,this预设绑定(Default Binding)「全域物件」,也就是window

但在ES5的严格模式下,禁止this自动指定为全域物件,这点要特别注意。

var seven = "江南七怪";
console.log(window.seven); //"江南七怪"
function monster(){
  console.log(this.seven + "脾气古怪");
  
}
monster();  //"江南七怪脾气古怪"

var obj = {
  seven : "七喜汽水",
  func: monster
} 

obj.func(); //"七喜汽水脾气古怪"

所以在全域环境中直接呼叫monster()函式时,this.seven是指向全域变数的var seven = "江南七怪";当monster()作为obj物件func属性的方法的时候,this.seven会指向obj物件的seven属性"七喜汽水"。

var seven = "江南七怪";
var call = function() {
	console.log(this.seven);
}

var soda = function(){
	let seven = "七喜汽水";
	this.call();
}

soda(); //"江南七怪"

soda()透过this.call()来叫用call(),这时call()里面的this.seven是指向全域变数的seven,所以得到的结果是"江南七怪"。

如何强制指定this

在JavaScript有三种方式可以强制指定this给function,这种方式也叫「显式绑定」,分别是:

  • .call()
  • .apply()
  • .bind()

先来说说.call与.apply

function funcA(){
	//做某件大事
}
funcA.call(context, arg1, arg2...)
funcA.apply(context,[arg1,arg2...])

上面的程序码式使用.call与.apply去呼叫执行funcA,第一个参数context为所带入的物件,也就是强制用那个物件来当成function执行时的物件。

.call与.apply作用一样,差别在.apply第一个参数(带入的物件)之後的参数以阵列方式传入,而.call则是使用逗号隔开。

let kuo = {
	name: "郭靖",
	wife: "黄蓉"
}

let yung = {
	name: "杨过",
	wife: "小龙女"
}

function funcA(){
	console.log(`${this.name}的老婆是${this.wife}`)
}

funcA.call(kuo) //郭靖的老婆是黄蓉
funcA.apply(yung) //杨过的老婆是小龙女

funcA.call(null,"周伯通","瑛姑")//的老婆是undefined 

我们可以看见this.name与this.wife绑定到带入的物件上。而this随着所带入的物件不同,指向也会动态地改变。

而bind的用法如下:

let kuo = {
	name: "郭靖",
	wife: "黄蓉"
}

let yung = {
	name: "杨过",
	wife: "小龙女"
}

function funcA(){
	console.log(`${this.name}的老婆是${this.wife}`)
}

let kuoWife = funcA.bind(kuo);
kuoWife()  //郭靖的老婆是黄蓉

let yungWife = funcA.bind(yung);
yungWife() //杨过的老婆是小龙女

藉由‵let kuoWife = funcA.bind(kuo) ‵也可以把this指向所带入的物件。

其实以上的应用,万变不离其宗,只要记得:「this代表的是function执行时所属的物件,而不是function本身」


<<:  Day29:刷起来! leetcode

>>:  细看seldon core所部署出来的POD在做什麽

Day12 按键修饰符

Day12 按键修饰符 今天来介绍一下按修饰符吧~ 键盘上每个按钮都有编号(keycode),当我们...

Dynamic Time Warping (DTW)

DTW 是什麽 当要计算时间序列资料的相似程度时,我们可以使用不同的距离计算方式。DTW就是其中一种...

day 5 knock, knock我要开始coroutine

coroutine神奇又好用,那我要怎麽开始呢? 官方提供了两种方法,launch和 async l...

DAY6 起手式--Nuxt.js常用套件安装

前言 不论在哪个环境开发,都会使用到一些插件、套件,我们应该如何在 Nuxt.js 使用呢?又要如何...

快速新增范例资料

接下来研究NoSQL的查询方式, 最好有大量范例资料使用. 可利用AWS的范例快速新增. 可先到此下...