在javascript中,类和构造函数之间有什么区别?

时间:2017-10-18 22:19:17

标签: javascript

类和构造函数都可用于创建对象。这两者的typeoffunction。那么,我何时应该使用类和构造函数?

2 个答案:

答案 0 :(得分:4)

类在技术上是构造函数。具有[[ Construct ]]内部方法的任何对象都被视为一个。所有构造函数都是函数,但并非所有函数都是构造函数。

Javascript中的函数可以有很多种。我们有正常的函数,箭头函数,类,方法,异步函数,异步箭头函数,生成器,异步生成器以及未来的生成器箭头函数。

在所有这些功能中,唯一可以构造某些功能的是class和普通功能。这些中没有一个具有[[ Construct ]]内部方法。

正常函数和类之间存在一些语义差异,如构造函数和可调用函数:

  • 只有类具有derived构造函数(构造模型略有不同)。
  • 不能调用类,只能通过new实例化。
  • 类具有super绑定(其中一部分与1相关)。
  • 当有class子句时,prototype(不是extends属性)的原型是超级构造函数。
  • prototype属性在类中不可写,对于普通函数是可写的。

其他一些可能与class不同但可以使用普通函数完成的事情:

  • class默认情况下代码是严格模式。
  • class使用原型中的方法。对于作为构造函数的常规函数​​,它们通常也是常规函数。这意味着您无法从类方法构造新对象。
  • 原型中的
  • class方法不可枚举。对于作为构造函数的常规函数​​,它们通常使用=定义,并使这些属性可枚举。

其他相关信息:

  • 在到达类声明/表达式之前,不会实例化类。顶级函数声明在函数调用开始时初始化,并且可以在整个范围内访问。
  • constructor(){ }中的
  • class是实际评估构造函数的唯一方法定义。方法不是构造函数。

答案 1 :(得分:2)

@Keith所说的是非常正确的,由于一些奇怪的原因,JS新手很难掌握,考虑这段代码:

旧学校

使用旧学校的方式,事情会语法上凌乱:

function _Thing() {}

function _Person(name, age, from) {
    this.name = name;
    this.age = age;
    this.from = from;
}

_Person.prototype = Object.create(_Thing.prototype);
_Person.prototype.constructor = _Person;//so easy to mess this up!

_Person.prototype.makeOlder = function () {
    this.age++;
};
_Person.prototype.toString = function () {
    return this.name;
};
_Person.FLORIDA = 1;
_Person.NEW_YORK = 2;


var _p = new _Person('rafael cepeda', 23, _Person.FLORIDA);
console.log(_p, _p instanceof _Person, _p instanceof _Thing);//_Person { name: 'rafael cepeda', age: 23, from: 1 } true true

新学校

ES6方式为OOP程序员提供了非常直观的感觉:

class Thing {}

class Person extends Thing {
    constructor(name, age, from) {
        super();
        this.name = name;
        this.age = age;
        this.from = from;
    }

    makeOlder() {
        this.age++;
    }

    toString() {
        return this.name;
    }

    static get FLORIDA() { return 1; }
    static get NEW_YORK() { return 2; }
}

var p = new Person('rafael cepeda', 23, Person.FLORIDA);
console.log(p, p instanceof Person, p instanceof Thing);//Person { name: 'rafael cepeda', age: 23, from: 1 } true true

注意ES6样式构造函数和旧学校构造函数之间的相似之处,看看原型方法定义;用新的方式,你甚至不必写出prototype这个词(这会吓到新人)。

因为它们基本上是相同的,所以它正确地创造了语法糖。在检查了两个构造函数之后,为什么typeof都返回function并不奇怪。