精简讨论Javascript 中的 this 问题
栏目: JavaScript · 发布时间: 6年前
内容简介:最近看了一些文章都有谈论 this 的问题。其实,总觉得并没想象那么难(傲娇脸...)。所以,我在此就想分享一下我的极简理解,也希望能帮助到大家~~~~话不多说,直接用例开干。 例一:分析:getAge 是谁调用的?
最近看了一些文章都有谈论 this 的问题。其实,总觉得并没想象那么难(傲娇脸...)。所以,我在此就想分享一下我的极简理解,也希望能帮助到大家~~~~
情况一:谁调用,this 就指向那个对象。
话不多说,直接用例开干。 例一:
// 1. 直接调用
function getAge() {
var age = 18
console.log(this.age) // undefined
console.log(this) // window
}
getAge()
复制代码
分析:getAge 是谁调用的?
- 写完整的话应该是 window.getAge().
- 调用对象就是 window,所以函数内部上下文环境就是 window.
- 当前环境下没有 window.age ,所以就是 undefined 啦.
注:严格模式下, window 环境下调用的函数的this 是 undefined,不指向 window。
'use strict'
function getAge() {
var age = 18
// console.log(this.age) // 直接语法报错,undefined 无法再找属性
console.log(this) // undefined
}
getAge()
复制代码
例二:
// 2. 对象调用
var obj = {
age: 19,
getAge() {
console.log(this.age)
console.log(this)
},
returnGetAgeFunc() {
return this.getAge
}
}
obj.getAge()
obj.returnGetAgeFunc()()
复制代码
首先是 obj.getAge(),答案是 19
和 obj
这个对象
- 这个 getAge 就是 obj,所以上下文环境是 obj 无可厚非。 所以第一个答案是 小明2,第二个答案是 obj 这个对象。
然后是 obj.returnGetAgeFunc() (), 答案是 undefined
和 window
obj.returnGetAgeFunc() === getAge
例三:
// 3. 嵌套深一层
var obj = {
age: 19,
innerObj: {
getAge() {
console.log(this.age)
console.log(this)
},
returnGetAgeFunc() {
return this.getAge
}
}
}
obj.innerObj.getAge() // undefined innerObj
obj.innerObj.returnGetAgeFunc()()
复制代码
分析:
- obj.innerObj 简单来说就是 innerObj 对象, 然后用 innerObj调用函数,当前 this 不就是 innerObj嘛。所以,age 是 obj 的属性,因此, this.age === undefined. this 指向就是 innerObj
- 第二个同理,obj.innerObj.returnGetAgeFunc() 这么长一截就是为了取出 obj.innerObj 中的 getName 函数。然后在 Window 环境下执行。this.age === undefined, this 指向就是 Window。
再用代码等量代换一次...别嫌我啰嗦,因为,和一些人讲过,但是他们没懂.. ~。~
var obj = {
age: 19,
innerObj: {
getAge() {
console.log(this.age)
console.log(this)
},
returnGetAgeFunc() {
return this.getAge
}
}
}
obj.innerObj.getAge()
obj.innerObj.returnGetAgeFunc()()
// 使用上完全等价下面
var innerObj: {
getAge() {
console.log(this.age)
console.log(this)
},
returnGetAgeFunc() {
return this.getAge
}
}
innerObj.getAge()
function getAge() {
console.log(this.age)
console.log(this)
}
// obj.innerObj.returnGetAgeFunc() == getName
getName() // obj.innerObj.returnGetAgeFunc()()
复制代码
情况二:自行改变当前环境下的this指向。
完全复制之前的事例,加一点东西来解释,尽可能的减少过多冗余信息接收。
改变执行函数内部 this 指向的有三个函数, call, apply, bind. 这里就不解释这三个函数的差异了。默认大家都知道~
// 1. 直接调用
var obj = {}
obj.age = 20
function getAge() {
var age = 18
console.log(this.age) // 20
console.log(this) // obj
}
getAge.call(obj)
复制代码
其实挺容易理解的,就是把函数的执行上下文环境的 this 换成了 obj。
同理:
// 2. 对象调用
var tempObj = { age: 20 }
var obj = {
age: 19,
getAge() {
console.log(this.age)
console.log(this)
},
returnGetAgeFunc() {
return this.getAge
}
}
obj.getAge.call(tempObj) // 20 tempObj
obj.returnGetAgeFunc().call(tempObj) // 20 tempObj
复制代码
最后一个就不用多说了。这里再补充一些。
比如通过 new 关键字得到的对象,调用内部函数时,this 指向的就是这个对象,其实就是使用了上述 call,apply,bind 函数来改变的。
情况三: ES6 箭头函数
使用箭头函数编程往往也被称为函数式编程,也是面向过程编程。 当我们从上往下的编写业务的时候,很多情况下,我们希望this 的指向是一致的,特别是回调函数中的 this。
因此,简单来说,this 指向
// 2. 对象调用
var tempObj = { age: 20 }
var obj = {
nonArrowFunc() {
// this === obj
return function() {
console.log(this) // tempObj
console.log(this.age) // 20
}
},
arrowFunc() {
// this === obj
return () => {
console.log(this) // obj
console.log(this.age) // undefined
}
}
}
obj.nonArrowFunc().call(tempObj)
obj.arrowFunc().call(tempObj) // 20 tempObj
复制代码
没有箭头函数时,上下文环境被更换成了 tempObj 使用箭头函数后,上下文环境使用运行环境的this.
再简单的说就是,箭头函数里面的this 不用自己函数上下文环境中的,用上一级的。
总结
因此,我归纳的 this 就是这三种,一般业务情况下,我们都不会搞得很复杂,this指向有问题,我们也会用一个变量来承接解决。 但是,面试的时候可能会比较多层,比较绕。如果不熟练的话,只需要按照我的第二种情况去等量替换,你就容易得到结果啦~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法设计与实验题解
王晓东 / 电子工业 / 2006-9 / 46.00元
《算法设计与实验题解》是与普通高等教育“十一五”国家级规划教材《计算机算法设计与分析》(第2版)配套的辅助教材,对主教材中的全部习题做了解答或给出了解题思路提示,并对主教材的内容进行了扩展,有些主教材中无法讲述的较深入的主题以习题的形式展现出来。为了提高学生解决实际问题的能力,《算法设计与实验题解》还将主教材中的许多习题改造成算法实现题,要求学生设计出算法并上机实现。作者还结合精品课程建设,进行了......一起来看看 《算法设计与实验题解》 这本书的介绍吧!