js 当中的this关键字很难? 记住这几条规则就够了

this关键字很难? 一层层给它剥开,发现它内心特别的纯洁

前言:在JavaScript中,this 是一个关键字,它的值取决于函数的调用方式。this 的作用是指向当前执行代码的对象,它在不同的情境下会有不同的值。所以this的指向是动态的。那我们要怎么判断this到底指向哪里呢?记住下面几条规则就够了。来来来,让我们一起来看看这个流氓this其实特别的守规则。

默认绑定规则

默认绑定规则:函数在哪个词法作用域中生效,this就指向哪里(独立调用的函数就是指向window)。

我们来举个简单的例子看一下

js 复制代码
var a=1
function foo(){
    console.log(this.a)
}

在全局声明了变量a=1,写了函数foo(),打印函数内部自带的关键字this,他会指向哪里呢?在浏览器的控制台运行,它是指向windows的,在这里我们要明白一个概念,this所在的函数在哪里生效,那么this指向这个地方的词法作用域,我们知道函数只有作用域没有词法作用域,所以指向windows这个全局词法作用域。

让我们在看一个例子 将上述的函数放在bar()函数中调用,那么this又会指向哪里呢?

js 复制代码
var a=1
function foo(){
    console.log(this)
}

function bar(){//bar的词法作用域是window
    var a=2
    foo()
}//foo是在bar的作用中调用,但是必须要知道bar的词法作用域中调用。
bar()

根据我们上面说的,this指向函数生效的那个词法作用域,那foo()函数是在bar()生效的,是不是指向bar()的词法作用域呢?看看结果到底指向哪

我们可以看到结果还是指向windows。理由很简单,像上文说的。this指向函数生效的词法作用域当中,this在bar()中被调用,自然是指向this的词法作用域那就是windows。

我们再来看一个例子

js 复制代码
function foo(){ 
    function bar(){
        console.log(this)
    }
    bar()
}
foo()

按照上面的规则,你分析一下,一步步的来,bar()函数在foo()中生效是吧,那应该指向foo()的词法作用域是吧,那是不是得指向foo()

结果:

为什么还是指向windows?是不是上面说的出错了,并没有。还记得我们说的啥嘛。函数没有词法作用域,只有作用域,那么this是指向词法作用域的,foo()函数没有词法作用域,只能向上找,找到Windows这个全局词法作用域。看图理解一下。

总结就一句话,独立调用的函数this都指向windos,因为this指向词法作用域,而函数没有词法作用域,只能指向全局词法作用域windows.

隐式绑定规则

隐式绑定规则:当一个函数被对象拥有,且调用时,函数的this指向对象。 继续看个例子理解一下吧

js 复制代码
function foo(){
    console.log(this.a)
}
var obj = {
    a:1,
    foo:foo
}
obj.foo()

我们写了一个函数foo(),并写了一个对象,将foo()函数放在obj对象中,并用通过obj对象调用,诶,是不是区别于上面的独立调用。来看看结果吧。

结果是1,是不是符合我们的说法,此时this指向的就是obj对象。

所以,隐式绑定规则很简单就是一个函数被对象函数拥有并且被对象调用,那么this指向的就是这个对象。

隐式丢失

隐式丢失:当函数被多个对象链式调用时,this指向引用函数的那个对象。 举个栗子看一下吧,什么是隐式丢失

js 复制代码
var obj = {
    a:1,
    foo:foo
}
var obj2={
    a:2,
    obj:obj
}
function foo(){
    console.log(this.a)
}
obj2.obj.foo()

我们写了一个函数并被obj对象拥有,obj2对象又拥有obj对象,那通过obj2调用,this指向哪里呢?

显然结果是1,指向obj,就近原则,谁引用就指向谁。

显示绑定

显示绑定:call,apply,bind,用这些方法可以直接选择this的对象 举个栗子

js 复制代码
function foo(){
    console.log(this.a);
}
var obj ={
    a:1
}
// foo.call(obj)
// foo.apply(obj)
let bar=foo.bind(obj)
bar()

看,通过这些方法也可以将this指向obj对象

new 绑定

this指向实例对象,这个我就不多赘述了,可以去查找一下new的使用规则,看看我以往的文章

箭头函数

函数是不是都有this这个关键字呢?不,箭头函数没有,所以箭头函数里面是没有this关键字的,它也就不能指向谁

总结

1.默认绑定规则:函数在哪个词法作用域中生效,this就指向哪里(独立调用的函数就是指向window)。

2.隐式绑定规则:当一个函数被对象拥有,且调用时,函数的this指向对象。

3.隐式丢失:当函数被多个对象链式调用时,this指向引用函数的那个对象。

4.显示绑定:call,apply,bind

5.new 绑定:this指向实例对象 到这this我们就分析的差不多了,是不是没有我们想象的那么难呢? 其实this是个挺纯洁的孩子呢,遵守这么多的规则。

相关推荐
独行soc1 分钟前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
王哲晓10 分钟前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
理想不理想v15 分钟前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云25 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
aPurpleBerry1 小时前
JS常用数组方法 reduce filter find forEach
javascript
sszmvb12341 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
王佑辉1 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
真忒修斯之船1 小时前
大模型分布式训练并行技术(三)流水线并行
面试·llm·aigc
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试