JacaScript语法:++运算符和闭包,全局变量和局部变量,类的继承

216 阅读3分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

  • ++运算符的理解和闭包的理解

function Foo() {
    var i = 0;
    return function() {
        console.log(i++);
    }
}

var f1 = Foo(),
    f2 = Foo();
f1();
f1();
f2();

分别输出0,1,0;这里涉及到的js知识点也不是很深,主要就是++运算符的理解和闭包的理解。首先Foo函数返回的也是一个函数,即function(){ console.log(i++),而这个函数的i引用的是外层函数的i,形成闭包,使得i的初始值为0。

var f1 = Foo( ),f2 = Foo( )这一句,前半句var f1 = Foo( )可以看做是var f1 = function( ){ console.log(i++)},。那么第一次执行f1的时候,自然是输出0,这里主要理解的是++运算符的使用,放在数字后表示后增,即先执行再+1,这里就是先执行console.log(i)之后i再加1,所以f1执行第二次的时候i已经变成了1,自然就输出1了。

后半句f2 = Foo() 可以看做是f2 = function( ){console.log(i++)},这没什么可说的,直接输出i的初始值0.

  • 全局变量和局部变量

var bb = 1;
function aa(bb) {
    bb = 2;
    alert(bb);
};
aa(bb);
alert(bb);

函数体内,bb并没有使用var来定义,按理说这个bb在预处理的时候应该是window的属性。但在这里,函数声明的时候,带了一个参数bb,也就是相当于在函数体内声明了var bb。所以,函数里的bb就是函数活动对象的属性。所以函数执行时会输出2。函数执行完后,函数的活动对象被销毁,也就是局部的这个bb被删除了,执行流进入到window,再输出bb,值就是1了。 没有使用var 等关键字声明的变量会被当成是window全局变量,比如 a=1

  • 类的继承

  1. 语法
// 父类
class Father{   
} 

// 子类继承父类
class  Son  extends Father {  
}       
  1. 示例
class Father {
      constructor(surname) {
        this.surname= surname;
      }
      say() {
        console.log('你的姓是' + this.surname);
       }
}

class Son extends Father{  // 这样子类就继承了父类的属性和方法
}
var damao= new Son('刘');
damao.say();      //结果为 你的姓是刘

以上代码运行结果:

在这里插入图片描述

  • 子类使用super关键字访问父类的方法

    //定义了父类
    class Father {
       constructor(x, y) {
       this.x = x;
       this.y = y;
       }
       sum() {
       console.log(this.x + this.y);
    	}
     }
    //子元素继承父类
        class Son extends Father {
       		 constructor(x, y) {
        		super(x, y); //使用super调用了父类中的构造函数
        	}
        }
        var son = new Son(1, 2);
        son.sum(); //结果为3
    

    注意:

    1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的

    2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)

    3. 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用

       // 父类有加法方法
       class Father {
         constructor(x, y) {
         this.x = x;
         this.y = y;
         }
         sum() {
         console.log(this.x + this.y);
         }
       }
       // 子类继承父类加法方法 同时 扩展减法方法
       class Son extends Father {
         constructor(x, y) {
         // 利用super 调用父类的构造函数 super 必须在子类this之前调用,放到this之后会报错
         super(x, y);
         this.x = x;
         this.y = y;
      
        }
        subtract() {
        console.log(this.x - this.y);
        }
      }
      var son = new Son(5, 3);
      son.subtract(); //2
      son.sum();//8
      

      以上代码运行结果为:

在这里插入图片描述

  1. 时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用.

    1. constructor中的this指向的是new出来的实例对象
    2. 自定义的方法,一般也指向的new出来的实例对象
    3. 绑定事件之后this指向的就是触发事件的事件源
  2. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象[