how subclass native class?

M

mikewse

How can I subclass a native class to get my own class with all the
function of the native clas, plus correct instanceof behaviour?

The scenario I'm thinking of is something like

function MyArray() {
Array.apply( this, arguments );
}
MyArray.prototype = new Array();
MyArray.prototype.constructor = MyArray;

var marr = new MyArray();
marr[0] = "abc";
marr.length == 1; // true
marr instanceof MyArray; // true

But this seems impossible due to the Array constructor returning a new
object even when called with my own "this" in the apply() above. Can
this be solved in any way?

Best regards
Mike
 
R

Richard Cornford

How can I subclass a native class to get my own
class with all the function of the native clas,
plus correct instanceof behaviour?

The scenario I'm thinking of is something like

function MyArray() {
Array.apply( this, arguments );
}
MyArray.prototype = new Array();
MyArray.prototype.constructor = MyArray;

var marr = new MyArray();
marr[0] = "abc";
marr.length == 1; // true
marr instanceof MyArray; // true

But this seems impossible due to the Array constructor
returning a new object even when called with my own "this"
in the apply() above. Can this be solved in any way?

You could not subclass an array and have a result that had the
characteristics of an array (specifically a self-adjusting/updating -
length - property) because the characteristic that makes an Array and
Array is internal to the array instance (its internal [[Put]] method).

Array objects may be modified by augmentation, or the array prototype
extended.

Richard.
 
M

mikewse

Thanks Richard,
You could not subclass an array and have a result that had the
characteristics of an array (specifically a self-adjusting/updating -
length - property) because the characteristic that makes an Array and
Array is internal to the array instance (its internal [[Put]] method).

Well, then I know that it is indeed not possible. Thanks anyway for
bringing the bad news ;-).
Array objects may be modified by augmentation, or the array prototype
extended.

Ok, I will have to consider these solutions instead. I was hoping to be
able to use instanceof for distinguishing between "plain" arrays and my
own, but this seems to be out of the question.

BTW: Does this subclassing limitation apply to all native classes
(Date, Number, ...) ? My own quick tests suggest it is so...
I've skimmed through a couple of JS books but didn't find this kind of
information. Do you have any good pointers to where to look in cases
like this?

Best regards
Mike Wilson
 
R

Richard Cornford

Thanks Richard,
You could not subclass an array and have a result that
had the characteristics of an array (specifically a
self-adjusting/updating - length - property) because the
characteristic that makes an Array and Array is internal
to the array instance (its internal [[Put]] method).

Well, then I know that it is indeed not possible. Thanks
anyway for bringing the bad news ;-).

At least I now know you did want the 'magic' length property rather than
just to inherit Array methods. Inheriting just array methods doesn't
work either, but that is because of a number of varying implementation
bugs in various language versions. Array.prototype.join is virtually the
only one that can be reliably used on an object that has an array as its
prototype (which is actually quite useful).
Ok, I will have to consider these solutions instead.
I was hoping to be able to use instanceof for
distinguishing between "plain" arrays and my own, but
this seems to be out of the question.

That makes it sound like augmentation will be your preferred option. But
that doesn't make using - instanceof - practical, though in all the
browser scripts I have ever written I have never had a reason to use -
instanceof -, and don't ever anticipate having to. It is very easy to
provide objects with a testable indicator of whatever you need to know
about them (if their normal properties are not sufficient in
themselves), and most of the time it is not necessary to care.
BTW: Does this subclassing limitation apply to all native
classes (Date, Number, ...) ?

More or less. Date, String, Number, Boolean and RegEx all use an
internal [[Value]] property that is inaccessible and cannot be
inherited, and an object inheriting from a function will not have
[[Call]] or [[Construct]] methods. Some methods of these objects are
specified as being applicable to other types of objects, but some bugs
exist in this area so outside a known environment it is not worth the
effort.
My own quick tests suggest it is so...
I've skimmed through a couple of JS books but didn't find
this kind of information. Do you have any good pointers to
where to look in cases like this?

The specification (ECMA 262, 3rd edition) is where you look for the
details of the language. It is not an easy read but will tell you what
to expect (and then experimentation will show you that what you should
expect mostly happens with a very few exceptions).

Richard.
 
M

mikewse

That makes it sound like augmentation will be your preferred option. But
that doesn't make using - instanceof - practical, though in all the
browser scripts I have ever written I have never had a reason to use -
instanceof -, and don't ever anticipate having to.

Yes, the duck typing thing would normally be ok. My aim with the array
subclasses in this case was to map typed Java lists on the server to
corresponding array classes in JS (I am already doing this with
objects).

F ex the class Person with the member "List<Address> addresses" would
be mapped to the corresponding JavaScript class Person (subclass to
Object) with a property "addresses" of class AddressArray (subclass to
Array).

So the whole thing with subclasses and instanceof is really to make it
easier for a programmer fluent with the server model, trying to map
everything as closely as possible. So the classes are a sort of "sugar"
to make the feel of the client's server API better.
The specification (ECMA 262, 3rd edition) is where you look for the
details of the language. It is not an easy read but will tell you what
to expect

Thanks, I had a look through it and yes, I will probably need to invest
some time to learn how to use it :).

Best regards
Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,145
Latest member
web3PRAgeency
Top