JavaScript中的类和函数

使用类时,必须使用new操作符

class User {
    constructor() {}
}
User(); // 错误,类构造器调用不能没有new

但是,为什么内置的Date可以:

Date();
new Date();

Date到底是类还是函数?

阅读 2.4k
4 个回答

首先要明确一点,JavaScript 中的 class 是语法糖,其本质还是基于原型的函数。既然是语法糖,就去掉语法糖

function User () {
  if (new.target === undefined) {
    throw new TypeError("Class constructor User cannot be invoked without 'new'");
  }
  // instance logic
}
User(); // 错误,类构造器调用不能没有new

function Date () {
  if (new.target === undefined) {
    // convert logic
  }
  // instance logic
}

MyDate()
new MyDate()

结果一目了然,就是 if 语句中的逻辑不一样,为什么会有这种区别呢,主要有两个原因:

  1. class 语法是 ES6 才引入的,Date 是在 Netscape JavaScript 1.1 就引入了,当时还处于 JS 的上古时期,JS 各种标准还没成立,各家公司有自己的实现,但是常用方式已经形成了事实标准,这就在后来的标准中保留了下来
  2. JS 对于 new Date()Date() 实现了不同的逻辑,Date()主要处理一些转换的逻辑,现在不建议使用了,更普遍的是调用 Date 上提供了一些静态方法转换,整个 Date 的实现都太基础,用起来不方便,所以有了一些第三方库,比如momentjsdate-fns等,提供了更容易使用的方法与接口

JavaScript中很奇妙,没有“类”这个严格概念。所谓构造函数也是函数,只是new操作符利用函数做了一些奇妙的操作。

class User {
    constructor() {}
}
User(); // 错误,类构造器调用不能没有new

这样之所以会报错,是因为class关键字的特效,帮你做了非new的处理。其实看Vue的源码应该也能看到:

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

使用 Date()的时候,这个是将其作为一个普通的函数在进行调用的.因此它返回的是一个字符串.
使用 new Date()的时候,这里是作为构造函数在使用的.因此它返回的是一个对象的.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题