使用this()调用重载构造方法的疑惑

为什么能够在构造器中的第一行使用this()来调用重载的构造方法?
this应该是一个地址值,地址值为什么能够调用构造方法呢?
还是说编译器在编译的时候,返现第一行是this(变量,变量……)这种形式之后,
就会在编译的时候在调用this()的语句出,将其替换为重载的构造方法的语句?
希望有人能够给我解解惑,非常感谢!

  1. 为什么能够在构造器中的第一行使用this()来调用重载的构造方法?
    答:我们的每个对象都有父类(至少有个Object类),我们在初始化当前对象时(即调用当前对象的构造方法),会先初始化父对象(先调用父类的构造方法)。只有保证当前对象的构造方法的第一行是”当前对象的构造方法“或”父类的构造方法“时,才能保证父对象和子对象的正确初始化。

  2. this应该是一个地址值,地址值为什么能够调用构造方法呢?
    答:

 Student student = new Student();
// student也是个地址值,为什么可以调用方法呢?
// 语法罢了。我们只需要记住这些规则即可。如果学了计算机组成原理,或许会更好理解一些。
 student.setName("张三");

如果答案对你有帮助,麻烦点下”解决“,关注我,持续为你解答。

this 如果在 类里面,那就是表示 当前类对象, this() 就是调用 类自身的构造方法,this(带参数) 就是调用带参数的
this.成员变量 ==》 访问当前类对象的成员变量
this.成员方法 ==》 访问当前类对象的成员方法

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7622260
  • 你也可以参考下这篇文章:父类方法中使用this,那么这个this指的是谁?
  • 除此之外, 这篇博客: 普通函数和箭头函数的this中的 箭头函数的this 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 默认指向在定义它时,它所处的对象,而不是执行时的对象, 定义它的时候,可能环境是window(即继承父级的this);

    箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssuper或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。

    箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:

    function Person(){
        this.age = 0;
    
        setTimeout(() => {
            this.age++; // this 指向 Person
            console.log(this);   //指向Person ,且age=1
        }, 1000);
    }
    
    var p = new Person();
    console.log(p);             //指向Person ,且 age=0

    eg01:

    var obj = {
        say: function () {
            setTimeout(() => {
                console.log(this)
            });
        }
    }
    obj.say(); // obj

    此时的this是定义它的对象,即继承了父级的this,父级中的this指的是obj,而非window

    eg02:

    var obj = {
        say: function () {
          var f1 = () => {
            console.log(this); // obj
            setTimeout(() => {
              console.log(this); // obj
            })
          }
          f1();
        }
      }
      obj.say()

    f1继承父级this指代的obj,不管f1有多层箭头函数嵌套,都是obj.

    eg03:

    var obj = {
        say: function () {
          var f1 = function () {
            console.log(this);    // window, f1调用时,没有宿主对象,默认是window
            setTimeout(() => {
              console.log(this); // window
            })
          };
          f1();
        }
      }
      obj.say()

    第一个this:f1调用时没有宿主对象,默认是window

    第二个this:继承父级的this,父级的this指代的是window.

    eg04:

    //1
    var x=1;
    var obj={
        x:2,
        say:()=>{
            console.log(this);     // window
            console.log(this.x);   // 1
        }
    }
    obj.say();
    
    //2
    var a=3;
    function test(){
        this.a=4;
        var fn=()=>{
            console.log(this);      //test
            console.log(this.a)     //4
        }
        fn();
    }
    var x=new test();
    
    //3
    var b=5;
    function test2(){
        this.b=6;
        let func=()=>{
            console.log(this);     //window
            console.log(this.b)    //6
        }
        func();
    }
    test2();

    第一个:ES6中定义的时候绑定this的继承的是父执行上下文里面的this,普通对象(非函数是,没有执行上下文的),因此第一个的this指向了window

    第二个:this指向new出来的对象,即test

    第三个:test2() 没有任何前缀,类似于全局函数,即  window.test2调用,所以此时调用的时候, this指的是window,

    执行上下文(Execution Context)

    执行上下文可以理解为函数执行的环境,每一个函数执行时,都会给对应的函数创建这样一个执行环境。

    每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况。

    • 全局环境:JavaScript代码运行起来会首先进入该环境
    • 函数环境:当函数被调用执行时,会进入当前函数中执行代码
    • eval(不建议使用,可忽略)

    因此在一个JavaScript程序中,必定会产生多个执行上下文,JavaScript引擎会以栈的方式来处理它们,这个栈,我们称其为函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,而处于栈顶的上下文执行完毕之后,就会自动出栈。



    作者:这波能反杀
    链接:https://www.jianshu.com/p/a6d37c77e8db
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    参考:
    https://www.cnblogs.com/lemonmonster/p/8482232.html

    https://www.cnblogs.com/var-chu/p/8476464.html

    https://www.cnblogs.com/dongcanliang/p/7054176.html