Class
ES6 的类其实是原型继承的语法糖:
当我们尝试用 class 去定义一个 Dog 类时:
其实完全等价于写了这么一个构造函数:
类的数据类型就是函数,类本身就指向构造函数。
不存在变量提升(hoist)
类不存在变量提升
私有方法
命名区分
一种做法是在命名上加以区别。
上面代码中,_bar
方法前面的下划线,表示这是一个只限于内部使用的私有方法。但是,这种命名是不保险的,在类的外部,还是可以调用到这个方法。
call调用
上面代码中,foo
是公开方法,内部调用了bar.call(this, baz)
。这使得bar
实际上成为了当前模块的私有方法。
Symbol 值
Symbol
值。
上面代码中,bar
和snaf
都是Symbol
值,
继承
子类必须在constructor
方法中调用super
方法
constructor
方法中调用super
方法上面代码中,constructor
方法和toString
方法之中,都出现了super
关键字,它在这里表示父类的构造函数,用来新建父类的this
对象。
子类必须在constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类自己的this
对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super
方法,子类就得不到this
对象。
只有调用super
之后,才可以使用this
关键字
super
之后,才可以使用this
关键字这是因为子类实例的构建,基于父类实例,只有super
方法才能调用父类实例。
上面代码中,子类的constructor
方法没有调用super
之前,就使用this
关键字,结果报错,而放在super
方法之后就是正确的。
super 作为函数调用时代表父类的构造函数
上面代码中,子类B
的构造函数之中的super()
,代表调用父类的构造函数。这是必须的,否则 JavaScript 引擎会报错。
super 作为对象时在普通方法中指向父类的原型对象。
上面代码中,子类B
当中的super.p()
,就是将super
当作一个对象使用。这时,super
在普通方法之中,指向A.prototype
,所以super.p()
就相当于A.prototype.p()
。
这里需要注意,由于super
指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super
调用的。
上面代码中,p
是父类A
实例的属性,super.p
就引用不到它。
最后更新于