JavaScript: использование конструктора без оператора 'new'

Пожалуйста, помогите мне понять, почему работает следующий код:

<script>
    var re = RegExp('\\ba\\b') ;
    alert(re.test('a')) ;
    alert(re.test('ab')) ;
</script>

В первой строке нет оператора new.

Насколько я знаю, конструктор в JavaScript - это функция, которая инициализирует объекты, созданные оператором new, и они не означает ничего вернуть.

Ответ 1

В общем случае, если что-то задокументировано как конструктор, используйте с ним new. Но в этом случае RegExp имеет определенное поведение "factory" для ситуации, когда вы назвали ее как функцию. См. Раздел 15.10.3 спецификации ECMAScript (JavaScript) (которая ссылается на исходящую спецификацию, номер раздела в новой спецификации совпадает, которую вы можете загрузить с главной страницы ECMA [с правой стороны], я не хочу напрямую ссылаться на PDF файл размером 4 МБ файл):

15.10.3 Конструктор RegExp, называемый функцией
15.10.3.1 RegExp (шаблон, флаги)
Если pattern - это объект R, чье свойство [[Class]] является "RegExp", а flags - undefined, тогда возврат R не изменяется. В противном случае вызовите конструктор RegExp (15.10.4.1), передав ему аргументы шаблона и флагов и верните объект, построенный этим конструктором.

Фактически вы можете определить свои собственные функции конструктора JavaScript, чтобы исключить ключевое слово new (обнаружив, что они были вызваны как функция вместо этого, и поворачиваются и правильно назовут), но я бы не предложил его как это приводит к вводящему в заблуждение коду.

Ответ 2

+1 У TJ Crowder есть это. Стандарт ECMAScript не подходит для определения поведения встроенных функций конструктора при вызове как простые функции. Часто он просто называет себя конструктором, но есть еще более сложные случаи.

конструкторы в javascript [...] не предназначены для возврата ничего

В общем случае конструктор может игнорировать this и просто возвращать независимый объект:

function Thing() {
    return {'foo': 1};
}

в этом случае вы можете одинаково использовать функцию в качестве конструктора (с new) или простой функцией.

Если конструктор ничего не возвращает, как обычный шаблон для конструкторов, сам оператор new гарантирует, что он возвращает новый объект, созданный и переданный как this. В этом случае вы должны использовать new.

Лучше не полагаться на конструктор, работающий как голой функции, и альтернативное поведение встроенных конструкторов редко используется, поэтому обычно вы должны придерживаться new.