学习ES56语法
http://es6.ruanyifeng.com/?spm=5176.100239.blogcont82041.28.r2N91S#docs/let
class以及继承
ES5定义类方法
Function Point(x,y)
{
This.x = x;
This.y =y;
}
Point.prototype.toString = function()
{
Return ‘(’ + this.x + ‘,’ + this.y + ‘)’;
}
ES5只能够在外部定义静态方法
Bar.classMethod = 方法
Var p = new Point(1,2);
ES6
//类中定义的属性方法,都是共有的
Class Point {
//类的静态方法
Static 属性名 =’’’;
x=’’;
Y=’’’
Constructor()
{
}
toString()
{
Return ‘’( + this.x + this.y +’)’;
}
//加上横线是私有方法标识,但是外部还是可以调用
_bar(baz) {
return this.snaf = baz;
}
}
toString()方法定义类似
Point.prototype ={
toString(){函数内容},
函数名(){函数体},
}
Point.prototype 类实例原型 对应属性变量是 __proto__
变相的私有方法
ES6实现私有方法,只能够将方法移动到模块之外,让方法称为模块的方法,这样可以在类内部调用此方法,而此方法就是类实例的私有方法
class Widget {
foo (baz) {
bar.call(this, baz);
}
// ...}
function bar(baz) {
return this.snaf = baz;}
ES6 为new命令引入了一个new.target属性,该属性一般用在在构造函数之中,返回new命令作用于的那个构造函数
需要注意的是,子类继承父类时,new.target会返回子类。
利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error('本类不能实例化');
}
}}
class Rectangle extends Shape {
constructor(length, width) {
super();
// ... }}
var x = new Shape(); // 报错var y = new Rectangle(3, 4); // 正确
ES6继承方式
ES6通过extends方式进行继承
ES5通过修改原型链来实现继承
ES5继承实质 先创建子类实例对象this,再将父类方法添加到this
ES6先创建 父类实例对象this,再用子类的构造函数修改this,所以必须构造函数中先调用 super方法
Object.getPrototypeOf(ColorPoint) === Point从子类中获取父类
也可以用此方法判断 一个类是否继承另一个类
Super关键字
Super作为函数代表父类构造函数,但是返回的是子类实例,它执行时候,指向的是子类构造函数
Super 作为对象使用时,在普通方法中,指向父类原型对象,在静态方法中指向父类
原型对象上定义属性,是通过类可以引用的,而在父类构造方法中属性则是实例属性,通过类无法引用
类A中有 A.protptype.x = 2;
则 子类构造方法中 super.x 是 2
子类__proto__属性,表示构造函数继承,总是指向父类
子类prototype属性 的 __proto__属性,表示方法 的继承,总是指向父类的prototype属性
class A {}
class B {}
// B 的实例继承 A 的实例Object.setPrototypeOf(B.prototype, A.prototype);
// B 的实例继承 A 的静态属性Object.setPrototypeOf(B, A);
const b = new B();
这两条继承链,可以这样理解:作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型(prototype属性)是父类的实例
第二种特殊情况,不存在任何继承。
class A {}
A.__proto__ === Function.prototype // true
A.prototype.__proto__ === Object.prototype // true
这种情况下,A作为一个基类(即不存在任何继承),就是一个普通函数,所以直接继承Function.prototype。但是,A调用后返回一个空对象(即Object实例),所以A.prototype.__proto__指向构造函数(Object)的prototype属性。
子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。
var p1 = new Point(2, 3);var p2 = new ColorPoint(2, 3, 'red');
p2.__proto__ === p1.__proto__ // falsep2.__proto__.__proto__ === p1.__proto__ // true
是否是??????
__proto__ 类原型
Prototype 返回类实例
原生继承
原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。
Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()
以前,这些原生构造函数是无法继承的,比如,不能自己定义一个Array的子类
ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的所有行为都可以继承。下面是一个继承Array的例子。
class MyArray extends Array {
constructor(...args) {
super(...args);
}}
var arr = new MyArray();
arr[0] = 12;
arr.length // 1
arr.length = 0;
arr[0] // undefined