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

相关推荐
Jiaberrr1 小时前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
我码玄黄1 小时前
THREE.js:网页上的3D世界构建者
开发语言·javascript·3d
爱喝水的小鼠2 小时前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
小晗同学2 小时前
Vue 实现高级穿梭框 Transfer 封装
javascript·vue.js·elementui
宇宙李2 小时前
2024java面试-软实力篇
面试·职场和发展
WeiShuai2 小时前
vue-cli3使用DllPlugin优化webpack打包性能
前端·javascript
forwardMyLife2 小时前
element-plus的面包屑组件el-breadcrumb
javascript·vue.js·ecmascript
mez_Blog3 小时前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
孙小二写代码3 小时前
[leetcode刷题]面试经典150题之1合并两个有序数组(简单)
算法·leetcode·面试
珊珊而川4 小时前
【浏览器面试真题】sessionStorage和localStorage
前端·javascript·面试