js深入(四)万脸懵圈的this指向

作为一个js菜鸡的我而言,在之前讲到过那么多的js链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了this指向上边,结果就是这个this指向指的我万脸懵逼(标题换字了,担心被河蟹),在经过漫长的通(gou)俗(pi)易(bu)懂(tong)的 ECMAScript规范阅读之后,分享一下我所认知的this指向

简而言之,js中this的指向不是在函数定义的时候确定的,而是在调用的时候创建阶段确定的,也就是说this指向谁,完全取决于函数的调用方式

常见的几种调用方式

  • 直接调用, 比如说

    function a() {
    console.log(this);
    }

    a();

这个例子里边this指向的是全局对象,在客户端的全局对象是window对象,在node 中的全局对象是global对象

    (function a() {
        function b() {
            console.log(this);  
        }
        b()
    })()
直接调用指的是直接用函数名称后边加()执行调用的函数,无论是否在全局作用域
  • 间接调用

    const obj ={

    name:'obj对象',
    a(){
        console.log(this)
    }

    }
    obj.a()

如图

在图中我们可以看到我们在对象里边调用对象里边的方法的时候,this指向的是obj对象,

或者说外边有一个函数 然后给一个obj对象的属性赋值

    const obj ={
        name:'obj对象',
        a(){
            console.log(this)
        }
    }
    obj.a()
    obj.b=function(){
        console.log(this,'b')
    }
    obj.b()

打印的结果都是obj对象

  • new调用

当我们他用过new 创建一个新的对象的时候,new会调用这个构造函数来创建一个对象,那么这个对象里边的this是这个被new的函数调用的,那么自然 new调用的时候,this就是指向这个新对象的

    function A(data) {
        this.data = data;
    }
    class B{
        constructor(data){
              this.data = data
        }
    }
    let a = new A("A");
    let b = new B("B");
    console.log(a.data);   
    console.log(b.data);   

如图

这个new,在创建对象的时候做了什么,我们会在下一篇博客里边仔细说明

  • 箭头函数中的this

箭头函数可以理解成是是一个语法糖,他没有自己的this绑定,箭头函数中使用的this是包含他的那个函数的this

比如说

    const obj = {
        a() {
            return () => {
                console.log(this);
            };
        }
    }    

上边这段代码被转译成es5 的时候如下

const obj = {
    a: function a() {
        var _this = this;
        return function () {
            console.log(_this);
        };
    }
};

综合以上所有的代码,得出一个结论就是,在js中this的绑定正常来讲是指向调用这个方法的对象来确定的,当然还有一些不正常的方法,可以改变this的指向

注意 ,下边介绍的几种方法,不能改变箭头函数的this指向,箭头函数本身是没有this绑定的,在介绍完不正常的情况后,再来说一说那些能够改变this指向的方法

ECMAScript 5.1 规范的this指向

      js中this的绑定正常来讲是指向调用这个方法的对象来确定的  
      

这句话在理论上是这么讲,在工作中正常的调用的话,这个理论是没有毛病的,在 ECMAScript 5.1 的规范里边规定,在js里边分为语言类型和规范类型

  • 语言类型

ECMAScript 里边的语言类型规定的是我们可以直接操作的一些类型,比如string number,object等等这些

  • 规范类型

规范类型ECMAScript 里边指的是一种抽象的规范,他们并不是让我们用来进行操作的,二是用来描述一些行为或者逻辑的,比如说typeof delete等等

ECMAScript 5.1 里边的this规定大概讲就是这样的,每个对象里边有一个Reference 规范类型,this会根据Reference这个规范类型进行赋值

ECMAScript 5.1

规范奉上 Reference 这个东西大家简单的理解成是()前边的那一块就好了,上边我们讲的那些正常的就是说左边是

  • 函数定义表达式
  • 属性访问表达式
  • 对象创建表达式
  • 属性创建表达式

这几种情况,在这几种情况的时候上边那句话是成立的

但是如果不是这上边的那几句话的时候,比如说括号里边是一个和函数相关计算或者一个运算符等等

这个时候this会指向undefined ,这个时候在非严格模式的情况下会被隐式转换成window对象

    var value = 1;

    var obj = {
      value: 2,
      a() {
        return this.value;
      }
    }
    
    console.log(obj.a());
    console.log((obj.a)());
    console.log((obj.a = obj.a)());
    console.log((false || obj.a)());
    console.log((obj.a, obj.a)());
    

记得之前看到过这个一个例子,运行结果如图

时间关系就说这些,下一篇博客会说new在运行时候过程和改变this指向的一些方法,
以上是我对this指向的一些认识,有不足的地方希望之处

急需100个bug续命

472 声望
13 粉丝
0 条评论
推荐阅读
代码路漫漫,整洁伴我行
恍恍惚惚写代码已经这么久了,阅读过得代码也可以算是有一些了,有的代码看一眼就没有再看下去的欲望,有的就像别人评价雷军那样,代码如诗一般。不知道大家有没有遇到过接手别人二手项目崩溃的时候,今天主要围...

不愧本心10阅读 2.4k

从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木140阅读 11.9k评论 10

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木60阅读 5.9k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.1k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木39阅读 7k评论 6

【关于Javascript】--- 正则表达式篇
基础知识一、元字符 {代码...} 二、量词 {代码...} 三、集合 字符类 {代码...} 四、分支 {代码...} 五、边界 开始结束 {代码...} 六、修饰符 {代码...} 七、贪婪模式和非贪婪模式js默认贪婪模式即最大可能的匹配...

Jerry35阅读 2.9k

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木32阅读 6k评论 9

急需100个bug续命

472 声望
13 粉丝
宣传栏