js回顾
js类构造方法:
构造方法**constructor
** 是一种用于创建和初始化class
创建的对象的特殊方法
在一个类中只能有一个名为“constructor”的特殊方法。一个类中出现多次构造函数 (constructor)
方法将会抛出一个 SyntaxError
错误。
在一个构造方法中可以使用super
关键字来调用一个父类的构造方法。
如果没有显式指定构造方法,则会添加默认的 constructor 方法。
如果不指定一个构造函数 (constructor) 方法,则使用一个默认的构造函数 (constructor)。
constructor链接
对于派生类,默认构造函数是:
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() d.task2()
|
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);
var child = new Child(); child.myMethod(2);
|
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 => { 方法体 }
|
- * 箭头函数里是没有this的,只会向上一层寻找(可能是window)
- * 箭头函数里是没有arguments的
- * 箭头函数不能作为构造函数
- ***** 箭头函数不能定义原型下的方法
函数作用域:
函数定义方式通常需要显式的指定函数名称,在代码执行前就被解释器加载到作用域中,这个特性可以让我们在函数定义之前就调用该函数。
既然提到函数声明,就要提到函数的作用域。函数作用域是指在函数内声明的所有变量在函数体内始终是可见的,这意味着,变量在声明之前已经可用。这个特性可以被称为声明提前,即在函数体内声明的所有变量,在声明之前已经有定义,但只有在执行到这个变量时才会被真正赋值。
函数直接量表达式也是用到了关键字function。一般这种定义方式适用于将它作为一个大的表达式的一部分,比如在赋值和调用过程中定义函数。通过函数直接量生成的函数,函数名称可以省略,此时就是一个匿名函数。(匿名函数谨慎使用)
js函数的三种定义方式