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是个挺纯洁的孩子呢,遵守这么多的规则。

相关推荐
倔强青铜三29 分钟前
苦练Python第20天:Python官方钦定的代码风格指南
人工智能·python·面试
倔强青铜三1 小时前
苦练Python第19天:断言与自定义异常
人工智能·python·面试
_一条咸鱼_1 小时前
LangChain正则表达式(19)
人工智能·面试·langchain
_一条咸鱼_1 小时前
Android Runtime安全上下文管理(76)
android·面试·android jetpack
_一条咸鱼_1 小时前
Android Runtime跨进程调用优化方案深度解析(75)
android·面试·android jetpack
遂心_1 小时前
用React Hooks + Stylus打造文艺范的Todo应用
前端·javascript·react.js
_一条咸鱼_1 小时前
OpenGL ES 深度剖析
android·面试·android jetpack
F2E_Zhangmo1 小时前
第一章 uniapp实现兼容多端的树状族谱关系图,创建可缩放移动区域
前端·javascript·uni-app
写字楼里看日出1 小时前
Electron入门教程:零基础手把手教你将网页打包成桌面应用
前端·javascript
JohnYan1 小时前
Bun技术评估 - 16 Debug
javascript·后端·debug