Зачем назначать что-то Something.prototype.constructor?

Я читал о том, как свойство прототипа Javascript работает вместе с наследованием, а затем начал просматривать код Angular.js и задал несколько вопросов.

Прежде всего, я прочитал, что свойство prototype указывает на объект, имеющий свойство «конструктор», которое указывает на исходную функцию, которая используется для создания объекта. Так, например:

// This is the constructor
function Shape() {
    this.position = 1;
}

// The constructor points back to the original function we defined
Shape.protoype.constructor == Shape;

Прототип также содержит любые другие методы или свойства, которые были определены для него нами или самим языком Javascript, и они являются общими для всех экземпляров объекта. Если вы хотите, чтобы объект с именем Square наследовал от Shape, вам нужно установить прототип Square равным новому экземпляру Shape, поскольку внутреннему свойству [[prototype]] Square.prototype присваивается значение открытого объекта свойства Shape.prototype. ,

function Square() {}
Square.prototype = new Shape();
var square = new Square();
square.position; // This will output 1

Это все имеет смысл для меня.

Тем не менее, код Angular.js, о котором у меня есть вопрос, кажется, связан со всем этим, но делает то, что я не понимаю. Кажется, он не имеет дело с наследованием, поэтому я могу понять, почему будут различия, но мне просто любопытно, почему они написали так, как они это сделали.

В Angular.js есть объект HashMap и объект Lexer, но они определены по-разному, но, кажется, создаются и используются одинаково точно. Сначала определяется конструктор Lexer, а затем они устанавливают прототип для литерала объекта, содержащего методы, которые должны использоваться всеми экземплярами Lexer. Это все имеет смысл. Что я не понимаю, так это то, почему они задают свойство «конструктор» и устанавливают его просто как «Lexer», если они не относятся к HashMap ниже.

var Lexer = function(options) {
    this.options = options;
};

// Notice they specify Lexer as the constructor even though they don't for HashMap below
Lexer.prototype = {
    constructor: Lexer,
    lex: function(text) { ... },
    is: function(ch, chars) { ... },
    peek: function(i) { ... },
    isNumber: function(ch) { ... },
    isWhitespace: function(ch) { ... },
    isIdent: function(ch) { ... },
    isExpOperator: function(ch) { ... },
    throwError: function(error, start, end) { ... },
    readNumber: function() { ... },
    readIdent: function() { ... },
    readString: function(quote) { ... }
};

Затем, если вы посмотрите на код HashMap, они делают то же самое, за исключением того, что они не определяют свойство конструктора. Почему это? Кажется, он работает точно так же, и я проверил, что конструктор все еще вызывается.

// The HashMap Constructor
function HashMap(array, isolatedUid) {
    if (isolatedUid) {
        var uid = 0;
        this.nextUid = function() {
            return ++uid;
        };
    }
    forEach(array, this.put, this);
}

HashMap.prototype = {
    put: function(key, value) { ... },
    get: function(key) { ... },
    remove: function(key) { ... }
};

Итак, является ли свойство конструктора необязательным, когда нет наследования, поэтому, может быть, один человек написал Lexer, а другой - HashMap, и один решил указать конструктор?

Ответы на вопрос(1)

Ваш ответ на вопрос