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

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

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

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

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

2 ответов


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

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

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


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

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

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

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

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

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

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