ES6 --(10)class使用、class继承

2019-11-29:

学习内容:


 

一、(1)class:

生成实例对象的传统方法:构造函数 

ES6的class:

  生成实例对象:var b = new Point(x, y)

  构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面:(以下3种方式都一样)

 

(2)constructor 方法:

  constructor方法,这就是构造方法,而this关键字则代表实例对象。constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象

  通过new命令生成对象实例时,自动调用该方法

 

(3)实例对象:

  类的所有实例共享一个原型对象:xxx.prototype。 __proto__属性 

  假如Photo有两个实例p1和p2,对p的原型添加一个printName方法,p2也能使用,不推荐这么用。

 

(4)get 和set 关键字:

  对定义的属性进行存值和取值函数,因此赋值和读取行为都被自定义了。

 

(5)用表达式写一个类:

  需要注意的是,这个类的名字是Me,但是Me只在 Class 的内部可用,指代当前类。在 Class 外部,这个类只能用MyClass引用。如果类的内部没用到的话,可以省略Me。

 

 

(6)注意点:

i、默认用严格模式。

ii、不存在提升,这个是和ES5生成实例对象最大的区别

iii、如果某个方法之前加上星号(*),就表示该方法是一个 Generator 函数。

⚠️iiii、this 的指向:

  避免如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境(由于 class 内部是严格模式,所以 this 实际指向的是undefined),应该将这个方法的this 绑定在构造函数中,或者用箭头函数(react就是利用这个)

iiiii、私有方法:没有给出实现方法,只有在方法名称前加 _ ,自我约束(类似于python)

 

(7)静态方法:

  加static 关键字变成静态方法,实例用不了,但是子类可以,这个定义在ts也有。

 

(8)new.target 属性:

  如果构造函数不是通过new命令或Reflect.construct()用的,new.target会返回undefined因此这个属性可以用来确定构造函数是怎么调用的。

 

能被实例:

Class 内部调用new.target,返回当前 Class: 

如果是继承的子类使用,new.target 返回子类的name。这样能限定一个类不能实例只能被(某一个子类)继承,更不能被实例:

 

 


 

二、class的继承:

(1)继承:

   Class 通过 extend 关键字继承。

  constructor方法和toString方法之中,都出现了super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。

  子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

  在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。

 

(2)Object.getPrototypeOf() 方法:

  该方法用于从子类获得父类,也能用于判断一个类是否继承了另一个类:

 

 

(3) super 关键字:

  既可以当作函数使用,也可以当作对象使用。

  i、super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错。

  假如A是父类,B继承了A,注意,super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例,因此super()在这里相当于A.prototype.constructor.call(this)。 

  ii、super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。super在普通方法之中,指向A.prototype,所以super.p()就相当于A.prototype.p()。 由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。

   使用super的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。例如:不能写 console.log(super)

 

(4)类的 prototype 属性和 __proto__ 属性:

  ES5 中每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。

  Class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。 

(1)子类的__proto__属性,表示构造函数的继承,总是指向父类。

(2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

   通过子类实例的__proto__.__proto__属性,可以修改父类实例的行为。

 

 (5)原生构造函数的继承:

原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。

  • Boolean()
  • Number()
  • String()
  • Array()
  • Date()
  • Function()
  • RegExp()
  • Error()
  • Object()

   ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的所有行为都可以继承。

   上面这个例子也说明,extends关键字不仅可以用来继承类,还可以用来继承原生的构造函数。因此可以在原生数据结构的基础上,定义自己的数据结构。

 

 

 

 

 

 

 

 

posted @ 2019-11-30 23:17  Marvin_Tang  阅读(621)  评论(0编辑  收藏  举报