《ES6学习4》Class
栏目: JavaScript · 发布时间: 5年前
内容简介:JS语言传统方法通过构造函数定义并生成新对象,ES6引入了Class这个概念作为对象的模板,通过class关键字可以定义类。上面的代码表明,类的数据类型就是函数,类本身指向构造函数。类的所有方法都定义在类的prototype属性上。在类的实例上调用方法,就是在调用原型上的方法。constructor方法是类的默认方法,通过new命令生成对象实例时自动调用该方法。如果没有显示定义,一个空的construtor方法会被默认添加。生成实例对象的写法和ES5一样,也是使用new命令,不同于ES5,如果忘记加new将
JS语言传统方法通过构造函数定义并生成新对象,ES6引入了Class这个概念作为对象的模板,通过class关键字可以定义类。
基本语法
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ',' + this.y + ')'; } Point.protortype.doStuff = function () { console.log('stuff'); } // 等同于 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } doStuff() { console.log('stuff'); } } typeof Point // "function" Point === Point.prototype.constructor // true
上面的代码表明,类的数据类型就是函数,类本身指向构造函数。类的所有方法都定义在类的prototype属性上。在类的实例上调用方法,就是在调用原型上的方法。constructor方法是类的默认方法,通过new命令生成对象实例时自动调用该方法。如果没有显示定义,一个空的construtor方法会被默认添加。
类的实例对象
生成实例对象的写法和ES5一样,也是使用new命令,不同于ES5,如果忘记加new将会报错。
class Point { } // 等同于 class Point { constructor() { } } var b = new Point(2, 3); // 生成Point实例 var c = Pint(2, 3) // 报错
Class表达式
与函数一样,Class可以使用表达式的形式定义。
const MyClass = class Me { getClassName() { return Me.Name; } }
需要注意的是这个类的名字是MyClass,而不是Me,Me只在Class内部有定义指代当前类。如果Class内部没有用到,那么可以省略Me。
let int = new MyClass(); int.getClassName() // Me Me.Name // 报错 const MyClass = class { getClassName() { return Me.Name; } } # 不存在变量提升 类不存在变量提升,与ES5完全不同。
new Foo() // 报错
class Foo {}
# Class的实例属性 Class的实例属性可以用等式写入类的定义中。
class MyClass {
myProp = 42;
constructor() {
console.log(this.myProp); // 42
}
}
new.target属性
ES6引入了new.target属性,(在构造函数中)返回new命令所作用的构造函数。如果构造函数不是通过new命令调用,那么new.target将会返回undefined,可以利用这个属性确定构造函数是怎么调用的。
function Person(name) { if (new.target !== undefined) { this.name = name; } else { throw new Error('必须使用new生成实例') } /*另一种写法 if (new.target == Person) { this.name = name; } else { throw new Error('必须使用new生成实例') }*/ } var Person = new Person('张三'); // 正确 var notAPerson = Person.call(person, '张三'); //报错
Class内部调用new.target,返回当前Class。
class Rectangle { constructor(length, width) { console.log(new.target === Rectangle); this.length = length; this.width = width; } } var obj = new Rectangle(3, 4); // 输出true
值得注意的是,之类基础父类时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(); // 正确
Class的继承
基本用法
Class可以通过extends关键字实现继承,之类必须在constructor方法中调用super方法,否则新建实例会报错。这是因为子类没有自己的this对象,而是继承父类的this对象。如果子类没有定义constructor方法,那么constructor方法(调用super)会被默认添加。
class Point { /* ... */} class ColorPoint extends Point { constructor() { //此处应调用super(); } } let cp = new ColorPoint(); // 报错
另一个注意点是,在子类的构造函数中只有在 调用super之后 才可以使用this关键字,否则会报错。
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y , color) { this.color = color; //报错 super(x, y); this.color = color; //正确 } }
super关键字
用作函数
super既可以当作函数使用,也可以当作对象使用。第一种情况,super作为函数调用时代表父类的构造函数。但是返回的之类的实例,即super内部的this指向实例。因此super()相当于A.prototype.constructor.call(this)。
class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); //作为函数时只能在子类的构造函数中 } } new A // A new B // B
作为对象
第二种情况,super作为对象时在在普通方法中指向父类的原型对象;在静态方法中指向父类。
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 这里相当于A.prototype.p() } } let b = new B();
this指向
ES6规定,通过super调用父类的方法时,super会绑定子类的this。如果通过super对某个属性赋值,这时的super就是this,赋值的属性会变成子类实例的属性。
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; } m() { super.print(); } } let b = new B(); b.m() // 3
以上所述就是小编给大家介绍的《《ES6学习4》Class》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 一文读懂监督学习、无监督学习、半监督学习、强化学习这四种深度学习方式
- 学习:人工智能-机器学习-深度学习概念的区别
- 统计学习,机器学习与深度学习概念的关联与区别
- 混合学习环境下基于学习行为数据的学习预警系统设计与实现
- 学习如何学习
- 深度学习的学习历程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。