It's not completely safe. When your constructor is called without new
, this
points to the global object.
var ticket = Ticket(); //this.document will point to the global document object
They key to understanding your code is that it uses this
which is a special keyword that can mean different things;
- When not within a function, it means
window
(<script>alert(this.name)</script>
) - When called as a standalone function without an object attached to it, (
alert()
),this
points to thewindow
object - When called with dot syntax
(ticket.resolve())
,this
points to the object on the left of the dot (ticket
). - When called as a constructor (
new Ticket
),this
is a new empty object that hasTicket.prototype
in its prototype chain. - When called from inline HTML handlers(
onclick="alert(this.id)"
),this
points to the HTML element where you attached the event - When called from functions like
setTimeout
,setInterval
and AJAX callbacks,this
usually points towindow
- When a function is called using
apply
orcall
, you can specify whatthis
will be - You can usually use
Function.bind
to make sure your function is called with the right
In the case for calling var ticket = Ticket()
, all your code like this.name = 'something'
would be creating or overwriting existing global variables, in this case, the name
of the window.
If you care about this problem you can mitigate this problem by doing the following.
Ticket = function (category, issuedBy, reissuable) {
if (!this instanceof Ticket) { // called as a function
return new Ticket(category, issusedBy, reissuable);
}
//properties
this.id = Date.now().toString();
To do it in a generic way, you can see this link http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html
Note that this would be probably unnecessary boiler plate code and can be avoided by following code conventions and enforcing them