写点什么

JavaScript class 类的基本使用方法你知道吗

作者:CRMEB
  • 2022 年 5 月 07 日
  • 本文字数:1390 字

    阅读完需:约 5 分钟

JavaScript class类的基本使用方法你知道吗

JavaScript 语言中,生成实例对象的传统方法是通过构造函数

class Point {  // ...}
typeof Point // "function"Point === Point.prototype.constructor // true
复制代码

上面代码表明,类的数据类型就是函数,类本身就指向构造函数使用的时候,也是直接对类使用 new 命令,跟构造函数的用法完全一致。

类的实例对象

class Bar {  doStuff() {    console.log('stuff');  }}
var b = new Bar();b.doStuff() // "stuff"
复制代码

构造函数的 prototype 属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的 prototype 属性上面。

class Point {  constructor() {    // ...  }
toString() { // ... }
toValue() { // ... }}
// 等同于
Point.prototype = { constructor() {}, toString() {}, toValue() {},};
复制代码

在类的实例上面调用方法,其实就是调用原型上的方法。类必须使用 new 调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用 new 也可以执行。

与 ES5 一样,类的所有实例共享一个原型对象。

var p1 = new Point(2,3);var p2 = new Point(3,2);
p1.__proto__ === p2.__proto__//true
复制代码

上面代码中,p1 和 p2 都是 Point 的实例,它们的原型都是 Point.prototype,所以__proto__属性是相等的。

这也意味着,可以通过实例的__proto__属性为“类”添加方法。

proto 并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用 Object.getPrototypeOf 方法来获取实例对象的原型,然后再来为原型添加方法/属性。

var p1 = new Point(2,3);var p2 = new Point(3,2);
p1.__proto__.printName = function () { return 'Oops' };
p1.printName() // "Oops"p2.printName() // "Oops"
var p3 = new Point(4,2);p3.printName() // "Oops"
复制代码

上面代码在 p1 的原型上添加了一个 printName 方法,由于 p1 的原型就是 p2 的原型,因此 p2 也可以调用这个方法。而且,此后新建的实例 p3 也可以调用这个方法。这意味着,使用实例的__proto__属性改写原型,必须相当谨慎,不推荐使用,因为这会改变“类”的原始定义,影响到所有实例

Class 表达式

与函数一样,类也可以使用表达式的形式定义。

const MyClass = class Me {  getClassName() {    return Me.name;  }};
复制代码

上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是 MyClass 而不是 Me,Me 只在 Class 的内部代码可用,指代当前类。

let inst = new MyClass();inst.getClassName() // MeMe.name // ReferenceError: Me is not defined上面代码表示,Me只在 Class 内部有定义。
复制代码

如果类的内部没用到的话,可以省略 Me,也就是可以写成下面的形式。const MyClass = class { /* ... */ };采用 Class 表达式,可以写出立即执行的 Class。

let person = new class {  constructor(name) {    this.name = name;  }
sayName() { console.log(this.name); }}('张三');
person.sayName(); // "张三"
复制代码

上面代码中,person 是一个立即执行的类的实例。

不存在变量提升

类不存在变量提升(hoist),这一点与 ES5 完全不同。ES6 不会把类的声明提升到代码头部。这种规定的原因与下文要提到的继承有关,必须保证子类在父类之后定义。

附件下载http://github.crmeb.net/u/defu

用户头像

CRMEB

关注

还未添加个人签名 2021.11.02 加入

CRMEB就是客户关系管理+营销电商系统实现公众号端、微信小程序端、H5端、APP、PC端用户账号同步,能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、会员维护、网络营销的一款企业应用

评论

发布
暂无评论
JavaScript class类的基本使用方法你知道吗_CRMEB_InfoQ写作社区