JavaScript知识回顾

js回顾

js类构造方法:

构造方法**constructor** 是一种用于创建和初始化class创建的对象的特殊方法

在一个类中只能有一个名为“constructor”的特殊方法。一个类中出现多次构造函数 (constructor)方法将会抛出一个 SyntaxError 错误。

在一个构造方法中可以使用super关键字来调用一个父类的构造方法。

如果没有显式指定构造方法,则会添加默认的 constructor 方法。

如果不指定一个构造函数 (constructor) 方法,则使用一个默认的构造函数 (constructor)。

constructor链接

函数
1
const add = (a,b) => {}

对于派生类,默认构造函数是:

1
2
3
constructor(...args) {
super(...args);
}

js原型链:

构造函数 - 继承机制

JS通过构造函数来生成实例。但是又出现了一个新的问题,在构造函数中通过this赋值的属性或者方法,是每个实例的实例属性以及实例方法,无法共享公共属性。所以又设计出了一个原型对象,来存储这个构造函数的公共属性以及方法。

我们可以看到,它的__proto__属性指向了一个function Function原型对象,该原型对象为JS中所有函数的原型对象,而其__proto__属性也还是指向了function Object原型对象,所以验证了原型链的尽头为null,这一说法。

在开发的时候,要注意不要通过实例对象去改变其构造函数原型对象,这样会对其他通过该构造函数生成的实例对象造成影响。

Js原型链


super

  • this关键词指向函数所在的当前对象
  • super指向的是当前对象的原型对象

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例

Class中的 super(),它在这里表示父类的构造函数,用来新建父类的 this 对象

子类没有自己的this对象,而是继承父亲的this对象,然后进行加工。如果不调用super,子类就得不到this对象

ES5的继承,实质上是先创造子类的实例对象this,然后再将父类的方法添加到this上(Parent.call(this)).
ES6的继承,需要先创建父类的this,子类调用super继承父类的this对象,然后再加工。

如果子类没有创建constructor,这个方法会被默认添加.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Demo{

constructor(x,y) {
this.x = x;
this.y = y;
}

customSplit(){
return [...this.y]
}

}

class Demo2 extends Demo{
constructor(x,y){
super(x,y);
}

customSplit(){
return [...this.x]
}

task1(){
return super.customSplit();
}

task2(){
return this.customSplit();
}
}

let d = new Demo2('hello','world');
d.task1() //["w", "o", "r", "l", "d"]
d.task2() //["h", "e", "l", "l", "o"]

super 在静态方法之中指向父类,在普通方法之中指向父类的原型对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}

Child.myMethod(1); // static 1

var child = new Child();
child.myMethod(2); // instance 2

ES6的箭头函数写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
//经典格式: 函数名 = ( 参数 ) => { 方法体 } 
const sum = (x,y)=>{
return x+y;
}
console.log(sum)

//当方法体只有一行时,花括号可以省略:
const sum1 = (x,y) => x+y;

console.log(sum1)

//当只有一个参数时,括号可以省略:
const sum2 = x => { 方法体 }
  1. * 箭头函数里是没有this的,只会向上一层寻找(可能是window)
  2. * 箭头函数里是没有arguments
  3. * 箭头函数不能作为构造函数
  4. ***** 箭头函数不能定义原型下的方法

函数作用域:

函数定义方式通常需要显式的指定函数名称,在代码执行前就被解释器加载到作用域中,这个特性可以让我们在函数定义之前就调用该函数。

既然提到函数声明,就要提到函数的作用域。函数作用域是指在函数内声明的所有变量在函数体内始终是可见的,这意味着,变量在声明之前已经可用。这个特性可以被称为声明提前,即在函数体内声明的所有变量,在声明之前已经有定义,但只有在执行到这个变量时才会被真正赋值。

函数直接量表达式也是用到了关键字function。一般这种定义方式适用于将它作为一个大的表达式的一部分,比如在赋值和调用过程中定义函数。通过函数直接量生成的函数,函数名称可以省略,此时就是一个匿名函数。(匿名函数谨慎使用)

js函数的三种定义方式

JS数据结构和数据类型

欢迎关注我的其它发布渠道