Когда вы вызываете функцию в качестве конструктора (здесь Person
), создается объект (пустой объект, внутренний прототип которого является прототипом функции конструктора - здесь Person.prototype
), и этот объект то, что было только что создано - это то, на что будет указывать значение this
внутри функции. Этот объект также будет неявно возвращен в конце конструктора.
Напротив, когда вы не используете new
, такой объект не создается; вы просто вызываете обычную функцию, и значение this
внутри нее будет зависеть от вызывающего контекста функции. Здесь, поскольку нет вызывающего контекста (вызываемая функция не является частью объекта), this
внутри функции будет либо глобальным объектом (в случае небрежного режима), либо undefined
(в случае строгого режима).
Итак, var qux = Person('qux');
запускает this.name = name
, где this
- глобальный объект.
С PersonSafe
вы проверяете, что this
экземпляр конструктора (что this
имеет внутренний прототип прототипа конструктора) - если вызывать без new
, этот тест не пройден, поскольку this
будет либо глобальным объектом, либо undefined
.
Обратите внимание, что arguments.callee
запрещено в строгом режиме, и строгий режим должен почти всегда использоваться. Попробуйте заменить на new.target
вместо:
function PersonSafe(name) {
if(!(new.target))
return new PersonSafe(name)
this.name = name; // run
}
var quxSafe = PersonSafe('qux');
console.log('PersonSafe qux: ',quxSafe);