如果我没猜错的话,许多刚入门JavaScript的小伙伴与我一样,看的都是ES5版本的JavaScript。是不是看到原型闭包等核心内容就头大了呢?很荣幸的告诉你,原型这一块在ES6中已经脱胎换骨了,没有你们想象中那么难了。废话不多说,进入正文!
1.类的创建
像以往的ES5,类.....哦不,应该称之为构造方法,其创建应该如下:
functionAnimal(name) {
this.name=name;
}
vardog=newAnimal("小狗");
console.log("动物的名字叫:"+dog.name);//动物的名字叫:小狗
对象的实例化是通过原型的,那么类又是怎么创建的呢?
classAnimal{
constructor(name){
this.name=name;
}
}
vardog=newAnimal("小狗");
console.log("动物的名字叫:"+dog.name);//动物的名字叫:小狗
学了java的同学是不是感觉很熟悉! 其中的constructor是类中的构造方法(另外声明一点,方法名前不需要加上function),对象的实例化与原型没有区别。由于只是浅谈ES6类的一些特性,不作深入分析.......
还有一个有趣的地方:
console.log(typeofAnimal);
你们猜这段代码会输出什么? class? nonononono!
与原型一样,都是function类型。
最后要注意的一点是:类不存在变量提升的问题。其设定的原因很简单,保证子类能够继承父类。下面我们就进入类的继承这块内容。
2.类的继承
像以往的ES5是怎么做到继承的?
functionAnimal(name){
this.name=name;
}
console.log("我会觅食");
}
console.log(this.name);
}
functiondog(name){
this.name=name;
}
dog.prototype=newAnimal();
vardog=newdog("小狗");
dog.sayName();//小狗
dog.action();//我会觅食
我用了最原始的方法写出了ES5的继承方法。
那相比于ES6的类的继承会怎么样呢?
让我们来看看ES6类的继承。
classAnimal{
constructor(name){
this.name=name;
}
action(){
console.log("我会觅食");
}
sayName(){
console.log(this.name);
}
}
classdogextendsAnimal{
constructor(name){
super(name);
}
}
varsmalldog=newdog("小狗");
smalldog.sayName();//小狗
smalldog.action();//我会觅食
extends是继承的意思。是不是感觉更加清晰明了了呢?
2.1 简单了解super关键字
在类中,super是指什么呢?学过java的小伙伴应该清楚,super指向父类;
super()则是调用父类的构造方法,括号内则是传进父类构造方法的参数。
那到底什么时候必须使用super关键字呢?
子类中加入构造方法(constructor)时,必须在其方法体内使用super();
classdogextendsAnimal{
constructor(name){
}
}
错误已经提示我们,必须在构造方法里面加入super();了吧!
classdogextendsAnimal{
}
如果不给子类加入构造方法,则不会提示错误,这是因为js引擎会默认的给所有类加上构造方法,如果是子类,则会默认加入构造方法,如下所示:
constructor(){
super();
}
说到这里的时候,必须提到一点:this关键字必须放在super()后,这是由于通过子类来实现对象实例化时,必须通过父类来实例化(不然是不会返回实例对象的),不然没有实例对象是不能通过this来修改实例对象的,父类返回实例对象类型为子类。是不是感觉很抽象,上一波代码!
classdogextendsAnimal{
constructor(name){
this.name=name;
super(name);
}
}
newdog("小狗");
成功报错!
classdogextendsAnimal{
constructor(name){
super(name);
this.name=name;
}
}
newdog("小狗");
没有报错了是吧。
3.类中的属性和方法
可能有的小伙伴误认为:"类中的方法和属性都是属于该类的吧"!非也,其实,类中的方法是属于原型的。如下所示:
classAnimal{
constructor(name){
this.name=name;
}
action(){
console.log("我会觅食");
}
sayName(){
console.log(this.name);
}
}
console.log(Animal.hasOwnProperty("action"));//false
console.log(Animal.hasOwnProperty("sayName"));//false
console.log(Animal.hasOwnProperty("name"));//true
console.log(Animal.prototype.hasOwnProperty("action"));//true
console.log(Animal.prototype.hasOwnProperty("sayName"));//true
console.log(Animal.prototype.hasOwnProperty("name"));//false
可以看出,类中的方法是属于原型的,而实例化的属性是不属于原型的。
下面的代码可以等同:
classAnimal{
sayName(){
console.log(this.name);
}
}
console.log(this.name);
}
当然,还有静态属性、静态方法的一些用法,这里就不一一介绍了。
领取专属 10元无门槛券
私享最新 技术干货