N
nick
So, I was making a simple constructor function for a List pseudoclass
(correct terminology?), and it looked like this:
....
function List()
{
for (var i=arguments.length; i--; )
this[arguments] = true;
}
....
This is kind of useful; now I can can create simple lists and use
for...in to iterate over them, where the variable on the left hand
side of 'in' is the value I actually want, not an index to the value I
want. But now I thought, what if someone does not know that they need
to use 'new' when calling a function-as-constructor, and they try
something like this?
var trees = List('maple', 'oak', 'palm');
In this case 'this' would reference the parent object of the function,
not the new List object being constructed. The variable 'trees' would
not contain a list, and the parent object would have all kinds of tree
names as properties now. Not good. So I thought this might be safer:
....
// constructor for simple list
function List()
{
if (className(this)!='List')
return List.apply(new List(), arguments);
for (var i=arguments.length; i--; )
this[arguments] = true;
return this;
}
// class name
function className (o)
{
var noname = '(undefined)';
if (o===null || o===undefined || !o.constructor)
return noname;
var c = String(o.constructor);
var n = /function\s+(\w+)\b/.exec(c);
return n && n[1] ? n[1] : noname;
}
....
This seems to work great, and now lists can be created by using 'new
List(...)' or just 'List(...)', interchangeably. To me, this seems
like a more foolproof solution with less potential for accidental
misuse. The question is, am I going about it the right way? Extracting
the class name from the constructor seems a little hackish. Is there a
better way to tell what "class" an object is, or some way to determine
whether a function was called with the 'new' keyword or not? TIA for
any advice.
-- Nick
(correct terminology?), and it looked like this:
....
function List()
{
for (var i=arguments.length; i--; )
this[arguments] = true;
}
....
This is kind of useful; now I can can create simple lists and use
for...in to iterate over them, where the variable on the left hand
side of 'in' is the value I actually want, not an index to the value I
want. But now I thought, what if someone does not know that they need
to use 'new' when calling a function-as-constructor, and they try
something like this?
var trees = List('maple', 'oak', 'palm');
In this case 'this' would reference the parent object of the function,
not the new List object being constructed. The variable 'trees' would
not contain a list, and the parent object would have all kinds of tree
names as properties now. Not good. So I thought this might be safer:
....
// constructor for simple list
function List()
{
if (className(this)!='List')
return List.apply(new List(), arguments);
for (var i=arguments.length; i--; )
this[arguments] = true;
return this;
}
// class name
function className (o)
{
var noname = '(undefined)';
if (o===null || o===undefined || !o.constructor)
return noname;
var c = String(o.constructor);
var n = /function\s+(\w+)\b/.exec(c);
return n && n[1] ? n[1] : noname;
}
....
This seems to work great, and now lists can be created by using 'new
List(...)' or just 'List(...)', interchangeably. To me, this seems
like a more foolproof solution with less potential for accidental
misuse. The question is, am I going about it the right way? Extracting
the class name from the constructor seems a little hackish. Is there a
better way to tell what "class" an object is, or some way to determine
whether a function was called with the 'new' keyword or not? TIA for
any advice.
-- Nick