核心提示:学习ES56语法https://es6.ruanyifeng.com/?spm=5176.100239.blogcont82041.28.r2N91S#docs/letclass以及继承ES5定义类方...
学习ES56语法
https://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