精简讨论Javascript 中的 this 问题

栏目: JavaScript · 发布时间: 5年前

内容简介:最近看了一些文章都有谈论 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(),答案是 19obj 这个对象

  • 这个 getAge 就是 obj,所以上下文环境是 obj 无可厚非。 所以第一个答案是 小明2,第二个答案是 obj 这个对象。

然后是 obj.returnGetAgeFunc() (), 答案是 undefinedwindow

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指向有问题,我们也会用一个变量来承接解决。 但是,面试的时候可能会比较多层,比较绕。如果不熟练的话,只需要按照我的第二种情况去等量替换,你就容易得到结果啦~


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Cypherpunks

Cypherpunks

Julian Assange、Jacob Appelbaum、Andy Müller-Maguhn、Jérémie Zimmermann / OR Books / 2012-11 / GBP 8.99

Cypherpunks are activists who advocate the widespread use of strong cryptography (writing in code) as a route to progressive change. Julian Assange, the editor-in-chief of and visionary behind WikiLea......一起来看看 《Cypherpunks》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具