🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## Class语法 > 1.简介 2.严格模式 3.constructor 方法 4.类的实例对象 5.私有方法和私有属性 6.this 的指向 7.name 属性 8.Class 的取值函数(getter)和存值函数(setter) 9.Class 的静态方法 10.Class 的静态属性和实例属性 11.new.target 属性 12.Class的继承 ### 1.简介 ~~~ //定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } ~~~ ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样 ~~~ function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; var p = new Point(1, 2); ~~~ ### 2.严格模式 类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。 ### 3.constructor 方法 ~~~ class Point { } // 等同于 class Point { constructor() {} } ~~~ ~~~ class Foo { constructor() { return Object.create(null); } } new Foo() instanceof Foo // false ~~~ ### 4.类的实例对象 ~~~ class Point { // ... } // 报错 var point = Point(2, 3); // 正确 var point = new Point(2, 3); ~~~ ### 5.私有方法和私有属性 ~~~ class Widget { // 公有方法 foo (baz) { this._bar(baz); } // 私有方法 _bar(baz) { return this.snaf = baz; } // ... } ~~~ ~~~ class Widget { foo (baz) { bar.call(this, baz); } // ... } function bar(baz) { return this.snaf = baz; } ~~~ ~~~ const bar = Symbol('bar'); const snaf = Symbol('snaf'); export default class myClass{ // 公有方法 foo(baz) { this[bar](baz); } // 私有方法 [bar](baz) { return this[snaf] = baz; } // ... }; ~~~ 私有属性的提案 ~~~ class Point { #x; constructor(x = 0) { #x = +x; // 写成 this.#x 亦可 } get x() { return #x } set x(value) { #x = +value } } ~~~ ### 6.this 的指向 ~~~ class Logger { printName(name = 'there') { this.print(`Hello ${name}`); } print(text) { console.log(text); } } const logger = new Logger(); const { printName } = logger; printName(); // TypeError: Cannot read property 'print' of undefined ~~~ ### 7.name 属性 ~~~ class Point {} Point.name // "Point" ~~~ ### 8.Class 的取值函数(getter)和存值函数(setter) ~~~ class MyClass { constructor() { // ... } get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop // 'getter' ~~~ ### 9.Class 的静态方法 ~~~ class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function ~~~ ### 10.Class 的静态属性和实例属性 ES6 明确规定,Class 内部只有静态方法,没有静态属性 ~~~ class Foo { } Foo.prop = 1; Foo.prop // 1 ~~~ ### 11.new.target 属性 ~~~ class Rectangle { constructor(length, width) { console.log(new.target === Rectangle); this.length = length; this.width = width; } } var obj = new Rectangle(3, 4); // 输出 true ~~~ ### 12.Class的继承 ~~~ class Point { } class ColorPoint extends Point { } ~~~ 该类通过extends关键字,继承了Point类的所有属性和方法 ~~~ class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 调用父类的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } } ~~~ Object.getPrototypeOf() 判断继承关系 ~~~ Object.getPrototypeOf(ColorPoint) === Point ~~~ super 关键字 super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。 第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。 ~~~ class A {} class B extends A { constructor() { super(); } } ~~~ ~~~ class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); } } new A() // A new B() // B ~~~ ~~~ class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 } } let b = new B(); ~~~ ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。 ~~~ class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.print(); } } let b = new B(); b.m() // 2 ~~~ ### 课后习题 1.用class语法改造下面的代码 ~~~ function Person (name,age) { this.name = name; this.age = age; } Person.prototype.getName =function(){ return this.name; } Person.prototype.getAge = function(){ return this.age; } ~~~ 2.请分析下面代码的运行结果 ~~~ class A { constructor(){ this.x=1; this.y=2; } getX () { console.log(this.x) } } class B extends A { constructor(){ super(); this.x=4; } getY(){ console.log(super.y) } } var b = new B(); b.getX() b.getY() ~~~