以松散模式编译ES6到ES5构造函数

时间:2018-01-20 17:52:42

标签: javascript

Exploring ES6 一书中,我正在阅读有关如何在松散模式下将构造函数编译为ES5的内容。一个例子是:

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

编译成:

"use strict";

function _classCallCheck(instance, Constructor) {
  if(!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Point = (function () {
    function Point(x, y) {
        _classCallCheck(this, Point);

        this.x = x;
        this.y = y;
    }

    Point.prototype.toString = function toString() { // (A)
        return "(" + this.x + ", " + this.y + ")";
    };

    return Point;
})();

我不明白这一行:

_classCallCheck(this, Point);

那么Point实际上意味着什么呢?它是指function Point吗?在这种情况下,this当然是Point的一个实例,因为它也引用function Point,因此_classCallCheck将始终返回true

2 个答案:

答案 0 :(得分:2)

  

那么Point究竟意味着什么呢?它是指Point函数吗?

_classCallCheck正在做的是检查是否创建了Point类的新实例。它阻止某人执行以下操作:

var test = Point(); // THROWS ERROR

在上一个代码段示例中,_classCallCheck(this, Point)this将是此代码的外部范围(可能是窗口)。

它会强制您实例化一个新实例:

var test = new Point(); // VALID

答案 1 :(得分:1)

  

那么Point究竟意味着什么呢?

这是Point函数,存储在var Point

  

在这种情况下,当然这是Point的一个实例,因为它也引用了函数Point,所以_classCallCheck将始终返回true。

不是这样。以Point不是this的实例的方式调用Point很容易。 ES6类本质上阻止以这种方式调用类名,但ES5没有,因此_classCallCheck用于确保保留ES6行为。观察:

"use strict";

function _classCallCheck(instance, Constructor) {
  if(!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Point = (function () {
    function Point(x, y) {
        _classCallCheck(this, Point);

        this.x = x;
        this.y = y;
    }

    Point.prototype.toString = function toString() { // (A)
        return "(" + this.x + ", " + this.y + ")";
    };

    return Point;
})();

// Invalid call prevented by _classCallCheck
Point(1, 2);