Named arguments and inheritance

Discussion in 'Javascript' started by Pacific Fox, Nov 10, 2006.

  1. Pacific Fox

    Pacific Fox Guest

    Hi all,

    haven't posted to this group before, but got an issue I can't work
    out... and hoping to get some help here ;-)

    I've got a base object that works fine with named arguments when called
    on it's own. However when I call the child object I get an error
    "[associative array name] has no properties (in firefox)."

    I simple test:

    Property = function( arg ) {
    /**
    * Private properties
    */
    var name = arg.name; // required, the name of the field

    /**
    * Priviliged methods, may be invoked publicly and may access private
    variables
    */
    this.getName = function() {
    return name;
    }
    };

    /**
    * Class for form field properties, extends property
    */
    FormProperty = function( arg ) {
    /**
    * Inheritance
    */
    this.super = Property;
    this.super( { name:arg.name } );
    this.prototype = new Property;
    }
    //property = new FormProperty( { name:"myVar" } )
    property = new Property( { name:"test" } )
    alert( property.getName() );

    Un comment //property = new FormProperty( { name:"myVar" } )
    to get the error.

    Thanks in advance for any help.
     
    Pacific Fox, Nov 10, 2006
    #1
    1. Advertising

  2. Pacific Fox

    Pacific Fox Guest

    Correct me if I am wrong, but doesn't that defeat the whole purpose of
    named arguments?


    David Golightly wrote:
    > Pacific Fox wrote:
    > > Hi all,
    > >
    > > haven't posted to this group before, but got an issue I can't work
    > > out... and hoping to get some help here ;-)
    > >
    > > I've got a base object that works fine with named arguments when called
    > > on it's own. However when I call the child object I get an error
    > > "[associative array name] has no properties (in firefox)."
    > >
    > > I simple test:
    > >
    > > Property = function( arg ) {
    > > /**
    > > * Private properties
    > > */
    > > var name = arg.name; // required, the name of the field
    > >
    > > /**
    > > * Priviliged methods, may be invoked publicly and may access private
    > > variables
    > > */
    > > this.getName = function() {
    > > return name;
    > > }
    > > };
    > >
    > > /**
    > > * Class for form field properties, extends property
    > > */
    > > FormProperty = function( arg ) {
    > > /**
    > > * Inheritance
    > > */
    > > this.super = Property;
    > > this.super( { name:arg.name } );
    > > this.prototype = new Property;
    > > }
    > > //property = new FormProperty( { name:"myVar" } )
    > > property = new Property( { name:"test" } )
    > > alert( property.getName() );
    > >
    > > Un comment //property = new FormProperty( { name:"myVar" } )
    > > to get the error.
    > >
    > > Thanks in advance for any help.

    >
    > Your problem is that your base class depends on always getting a valid
    > object for its argument, and you're not providing it one when you
    > subclass within the FormProperty constructor. You can't use this
    > technique to subclass if your base constructor makes assumptions about
    > always getting valid arguments, because your arguments might not be
    > available at creation time.
    >
    > Try this instead:
    >
    > Property = function() {
    > // use the arguments collection, an Array-like builtin that
    > contains the arguments passed into a function
    > if (arguments[0])
    > var name = arguments[0].name; // required, the name of the
    > field
    > // otherwise, we're subclassing and can skip this
    >
    > this.getName = function() {
    > return name;
    > }
    > };
    >
    > FormProperty = function( arg ) {
    > // use function.apply - it calls function Property using the first
    > parameter as "this"
    > // See also
    > http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply
    > Property.apply(this, [arg]);
    > }
    > FormProperty.prototype = new Property;
    > property = new FormProperty( { name:"myVar" } )
    > alert( property.getName() );
     
    Pacific Fox, Nov 10, 2006
    #2
    1. Advertising

  3. Pacific Fox

    Pacific Fox Guest

    OK, it seems to work, but I don't see how it works as the constructor
    for Property does not have any arguments, i'm a bit puzzled...

    property = new Property( { name:"myVar" } );



    Pacific Fox wrote:
    > Correct me if I am wrong, but doesn't that defeat the whole purpose of
    > named arguments?
    >
    >
    > David Golightly wrote:
    > > Pacific Fox wrote:
    > > > Hi all,
    > > >
    > > > haven't posted to this group before, but got an issue I can't work
    > > > out... and hoping to get some help here ;-)
    > > >
    > > > I've got a base object that works fine with named arguments when called
    > > > on it's own. However when I call the child object I get an error
    > > > "[associative array name] has no properties (in firefox)."
    > > >
    > > > I simple test:
    > > >
    > > > Property = function( arg ) {
    > > > /**
    > > > * Private properties
    > > > */
    > > > var name = arg.name; // required, the name of the field
    > > >
    > > > /**
    > > > * Priviliged methods, may be invoked publicly and may access private
    > > > variables
    > > > */
    > > > this.getName = function() {
    > > > return name;
    > > > }
    > > > };
    > > >
    > > > /**
    > > > * Class for form field properties, extends property
    > > > */
    > > > FormProperty = function( arg ) {
    > > > /**
    > > > * Inheritance
    > > > */
    > > > this.super = Property;
    > > > this.super( { name:arg.name } );
    > > > this.prototype = new Property;
    > > > }
    > > > //property = new FormProperty( { name:"myVar" } )
    > > > property = new Property( { name:"test" } )
    > > > alert( property.getName() );
    > > >
    > > > Un comment //property = new FormProperty( { name:"myVar" } )
    > > > to get the error.
    > > >
    > > > Thanks in advance for any help.

    > >
    > > Your problem is that your base class depends on always getting a valid
    > > object for its argument, and you're not providing it one when you
    > > subclass within the FormProperty constructor. You can't use this
    > > technique to subclass if your base constructor makes assumptions about
    > > always getting valid arguments, because your arguments might not be
    > > available at creation time.
    > >
    > > Try this instead:
    > >
    > > Property = function() {
    > > // use the arguments collection, an Array-like builtin that
    > > contains the arguments passed into a function
    > > if (arguments[0])
    > > var name = arguments[0].name; // required, the name of the
    > > field
    > > // otherwise, we're subclassing and can skip this
    > >
    > > this.getName = function() {
    > > return name;
    > > }
    > > };
    > >
    > > FormProperty = function( arg ) {
    > > // use function.apply - it calls function Property using the first
    > > parameter as "this"
    > > // See also
    > > http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply
    > > Property.apply(this, [arg]);
    > > }
    > > FormProperty.prototype = new Property;
    > > property = new FormProperty( { name:"myVar" } )
    > > alert( property.getName() );
     
    Pacific Fox, Nov 10, 2006
    #3
  4. Pacific Fox wrote:
    > Correct me if I am wrong, but doesn't that defeat the whole purpose of
    > named arguments?


    Javascript does not have named arguments at all. What you are doing is
    creating a new object for each function call using an object
    literal/initaliser, and assigning values to the named properties of
    that object, so the object becomes the single argument to the function
    call. This introduces a runtime overhead and results in the creation of
    many more objects that are necessary, which, given how low priority
    browser garbage collection is, will slow down, for example, IE
    considerably.

    Richard.
     
    Richard Cornford, Nov 10, 2006
    #4
  5. Pacific Fox wrote:
    > Hi all,
    >
    > haven't posted to this group before, but got an issue I can't work
    > out... and hoping to get some help here ;-)
    >
    > I've got a base object that works fine with named arguments


    Javascript does not have named arguments at all.

    > when called
    > on it's own. However when I call the child object I get an error
    > "[associative array name] has no properties (in firefox)."


    That is _absolutely_not_ the error you received (as javascript has no
    'associative arrays'). If you want people to help you debug your code
    it is a much better idea to post the errors that the code actually
    generates (as we all have lots of experience interpreting real error
    messages, and very little interest in fictional ones).

    > I simple test:
    >
    > Property = function( arg ) {


    Why not just use a named Function Declaration instead of this
    assignment of the value of a Function Expression? Generaly it is
    considered bad practice to be creating properties of the global object
    at runtime rather than using pre-declared global variables.

    > /**
    > * Private properties
    > */
    > var name = arg.name; // required, the name of the field
    >
    > /**
    > * Priviliged methods, may be invoked publicly and may access private
    > variables
    > */
    > this.getName = function() {
    > return name;
    > }
    > };
    >
    > /**
    > * Class for form field properties, extends property
    > */
    > FormProperty = function( arg ) {
    > /**
    > * Inheritance
    > */
    > this.super = Property;


    The word "super" is a FutureReservedWord in javascript, so it cannot be
    used as an Identifier, and so cannot appear in a dot notation property
    accessor. Some browsers may put up with this, but it is still
    officially a syntax error and will be treated as a syntax error in at
    least some environments.

    > this.super( { name:arg.name } );


    Why do this? Why create a new object with a - name - property and give
    it the value of the name property of the object passed in as an
    argument to the function call when you can just pass the argument
    object on to at this point?

    > this.prototype = new Property;


    This is:-

    1. The cause of your error, as no argument is being sent to the
    Property constructor but it is treating its argument as if it was an
    object.

    2. Pointless, as the call to this.super (where it has not resulted in a
    syntax error) will have added the - getName - method so masked the only
    public member of any Property instance created for the prototype.

    3. Stupid, because it is certainly not doing what it appears to be
    intended to do. When an object is constructed the assignment of the
    value of the constructor's prototype property to the new object's
    internal [[Prototoype]] property happens before the execution of the
    constructor's body code. Thus the first instantiation of an object with
    FormProperty will use the default - FormProperty.prototype - value as
    its [[Prototype]], the second instance will use the Property object
    created during the first instantiation, the third the Property object
    created during the second instantiation, and so on. If the prototype
    chain had any significance in the defining of any of these objects the
    fact that they would all have a different prototype, and particularly
    the fact that the first object's prototype was not an instance of the
    expected object, would destroy the likeness that is expected when
    implementing the 'class' concept in javascript.

    4. Doubly stupid because the point of prototype inheritance it to have
    may object instances sharing the same prototype, and so sharing single
    function objects for its methods (where that is acceptable) and single
    default values for its properties. creating a second object with each
    object constructed is wasteful.

    > }
    > //property = new FormProperty( { name:"myVar" } )
    > property = new Property( { name:"test" } )
    > alert( property.getName() );
    >
    > Un comment //property = new FormProperty( { name:"myVar" } )
    > to get the error.
    >
    > Thanks in advance for any help.


    Where ever you are learning to write javascript like this is not a good
    source of information on the subject.

    Richard.
     
    Richard Cornford, Nov 10, 2006
    #5
  6. David Golightly wrote:
    <snip>
    > Your problem is that your base class depends on always getting a
    > valid object for its argument, and you're not providing it one when you
    > subclass within the FormProperty constructor. ...

    <snip>
    > Try this instead:
    >
    > Property = function() {
    > // use the arguments collection, an Array-like builtin that
    > contains the arguments passed into a function
    > if (arguments[0])
    > var name = arguments[0].name; // required, the name of the
    > field
    > // otherwise, we're subclassing and can skip this
    >
    > this.getName = function() {
    > return name;
    > }
    > };


    Wouldn't it be considerably simpler just to ensure that the calls to
    the Property constructor were provided with appropriate arguments?
    After all the only time it is being called without them is when
    assigned to a prototype, so a dummy - name - would be harmless as it
    would be masked on real instances.

    > FormProperty = function( arg ) {
    > // use function.apply - it calls function Property using the first
    > parameter as "this"
    > // See also
    > http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply
    > Property.apply(this, [arg]);


    With a single argument (indeed with a known list of arguments. as must
    be the case here) the - call - method is more appropriate, and avoids
    the overhead of creating an Array object to pass on those arguments.

    However, the use of either sacrifices computability with some of the
    older of the browsers currently in use. Neither methods were introduced
    in JScript prior to IE 6. The technique used in the OP's code achieves
    as much as any use of apply/call does (syntax error not withstanding),
    leaves the object instances flagged with information about their
    'superclass' and is computable with all current browsers.

    Richard.
     
    Richard Cornford, Nov 10, 2006
    #6
  7. Pacific Fox

    Pacific Fox Guest

    Thanks, I realize they are not really named arguments (as javascript
    does not support that), but I figured anyone else would understand that
    as well. I really didn't want to go into a long story about that.

    Whatever you want to call it, however you want to see it, it allows to
    me to call functions without having to specify every parameter, i.e.
    someMethod( "some value", null, null, null, null, null, null, null,
    null, null, "and another value" )

    If this was on the server side I might have agreed with you, but since
    its on the client side I am not going to worry about these few extra
    objects. I wish I just got an answer to the problem, instead of going
    into whats right and wrong, and best practise and "make myself feel
    gooders" ;-)


    Richard Cornford wrote:
    > Pacific Fox wrote:
    > > Correct me if I am wrong, but doesn't that defeat the whole purpose of
    > > named arguments?

    >
    > Javascript does not have named arguments at all. What you are doing is
    > creating a new object for each function call using an object
    > literal/initaliser, and assigning values to the named properties of
    > that object, so the object becomes the single argument to the function
    > call. This introduces a runtime overhead and results in the creation of
    > many more objects that are necessary, which, given how low priority
    > browser garbage collection is, will slow down, for example, IE
    > considerably.
    >
    > Richard.
     
    Pacific Fox, Nov 13, 2006
    #7
  8. Pacific Fox

    Pacific Fox Guest

    > Javascript does not have named arguments at all.

    http://www.google.com.au/search?hl=en&q=javascript associative array&meta=
    378,000 results must be wrong to

    > That is _absolutely_not_ the error you received (as javascript has no
    > 'associative arrays'). If you want people to help you debug your code
    > it is a much better idea to post the errors that the code actually
    > generates (as we all have lots of experience interpreting real error
    > messages, and very little interest in fictional ones).


    I included the code below so that individual tests could be run, I even
    made the code smaller so that only the relevant items where there,
    instead of the 200 lines of code the classes really are.

    > Why not just use a named Function Declaration instead of this
    > assignment of the value of a Function Expression? Generaly it is
    > considered bad practice to be creating properties of the global object
    > at runtime rather than using pre-declared global variables.


    I'm not quite sure I understand. do you mean;

    function = argument() {
    this.variable = "some value"
    }

    and pass that to the method call?

    > The word "super" is a FutureReservedWord in javascript, so it cannot be
    > used as an Identifier, and so cannot appear in a dot notation property
    > accessor. Some browsers may put up with this, but it is still
    > officially a syntax error and will be treated as a syntax error in at
    > least some environments.
    >
    > > this.super( { name:arg.name } );


    Cool, I'll call it superClass from here on.

    > Why do this? Why create a new object with a - name - property and give
    > it the value of the name property of the object passed in as an
    > argument to the function call when you can just pass the argument
    > object on to at this point?


    It was a demonstration to allow anyone interested to see the error...

    > 1. The cause of your error, as no argument is being sent to the
    > Property constructor but it is treating its argument as if it was an
    > object.


    Here it all starts to make sense, this is what I was after, the object
    is created without the arguments. Yes, thanks... Now how to overcome
    this.

    > 2. Pointless, as the call to this.super (where it has not resulted in a
    > syntax error) will have added the - getName - method so masked the only
    > public member of any Property instance created for the prototype.


    I don't understand.

    > 3. Stupid, because it is certainly not doing what it appears to be
    > intended to do. When an object is constructed the assignment of the
    > value of the constructor's prototype property to the new object's
    > internal [[Prototoype]] property happens before the execution of the
    > constructor's body code. Thus the first instantiation of an object with
    > FormProperty will use the default - FormProperty.prototype - value as
    > its [[Prototype]], the second instance will use the Property object
    > created during the first instantiation, the third the Property object
    > created during the second instantiation, and so on. If the prototype
    > chain had any significance in the defining of any of these objects the
    > fact that they would all have a different prototype, and particularly
    > the fact that the first object's prototype was not an instance of the
    > expected object, would destroy the likeness that is expected when
    > implementing the 'class' concept in javascript.
    >
    > 4. Doubly stupid because the point of prototype inheritance it to have
    > may object instances sharing the same prototype, and so sharing single
    > function objects for its methods (where that is acceptable) and single
    > default values for its properties. creating a second object with each
    > object constructed is wasteful.



    > Where ever you are learning to write javascript like this is not a good
    > source of information on the subject.



    I got the code from
    http://developer.mozilla.org/en/doc...e:The_Employee_Example:Creating_the_Hierarchy
    which I would think is a reliable source....

    But would love to see your solution to this, allowing the base class to
    be extended...
     
    Pacific Fox, Nov 13, 2006
    #8
  9. Pacific Fox wrote:
    > Thanks, I realize they are not really named arguments (as javascript
    > does not support that), but I figured anyone else would understand that
    > as well.


    Not a good assumption. Attaching inappropriate terminology to
    javascript directly leads to many misconceptions and disappointed
    expectations for people who are just learning the language (like you
    are). "Named arguments" implies that the mechanics are handled
    internally and efficiently by the implementation, that is a long way
    from the case. While calling what you are doing what it is; creating a
    new object instance as a vehicle for passing argument with each
    function call, gives the reader a better understanding of what is going
    on, and the implications of doing it.

    > I really didn't want to go into a long story about that.
    >
    > Whatever you want to call it, however you want to see it, it allows to
    > me to call functions without having to specify every parameter,


    You don't have to specify every parameter is javascript. You just have
    to specify every parameter up to and including the last one that must
    be included.

    > i.e.
    > someMethod( "some value", null, null, null, null, null, null, null,
    > null, null, "and another value" )


    Think about that for a moment. The vast bulk of functions have 3 or
    fewer parameters, and the vast bulk of function calls must provide an
    argument for each parameter. Designing functions to take optional
    arguments is very much the exception, and even when it is done the
    designer gets to judge the likelihood of any particular parameter being
    omitted and so arrange their parameters such that the right most is the
    one most likely to be omitted in practice, the one to its left if next
    most likely to be omitted and so on.

    Thus you proposed example, with 10 optional arguments and the one being
    provided being the one least likely to be provided really is a very
    exceptional case. And in such a very exceptional case a little extra
    writing to provide values for the otherwise unused arguments does not
    seem that arduous.

    But rather than that you would address this really exceptional case by
    imposing the runtime overhead of creating a new object for each and
    every function call. That is disproportionate to the point of being
    stupid.

    > If this was on the server side I might have agreed with you, but since
    > its on the client side I am not going to worry about these few extra
    > objects.


    Those "few extra objects" are going to add up. Its one new object per
    function/method/constructor call, and the more complex your code
    becomes the more function/method/constructor calls you will make.

    > I wish I just got an answer to the problem, instead of going
    > into whats right and wrong, and best practise and "make myself feel
    > gooders" ;-)

    <snip>

    If you are satisfied to write code that barely works.

    Richard.
     
    Richard Cornford, Nov 13, 2006
    #9
  10. Pacific Fox wrote:
    >> Javascript does not have named arguments at all.

    >
    > http://www.google.com.au/search?hl=en&q=javascript associative array&meta=
    > 378,000 results must be wrong to


    And the relationship between "named arguments" and 'associative arrays'
    is?

    But yes, there are no associative arrays in javascript no matter how
    widely the story is put about that there are. You can tell that there
    are no associative arrays in javascript by proposing a formal
    definition of what an associative array is that excludes things that
    are definitely not associative arrays (such as the Java Vector class).
    You will find that any such definition also excludes the javascript
    object.

    >> That is _absolutely_not_ the error you received (as javascript
    >> has no 'associative arrays'). If you want people to help you
    >> debug your code it is a much better idea to post the errors
    >> that the code actually generates (as we all have lots of experience
    >> interpreting real error messages, and very little interest in fictional
    >> ones).

    >
    > I included the code below so that individual tests could be run, I even
    > made the code smaller so that only the relevant items where there,
    > instead of the 200 lines of code the classes really are.


    You still gave a false report of the error message.

    >> Why not just use a named Function Declaration instead of this
    >> assignment of the value of a Function Expression? Generaly it is
    >> considered bad practice to be creating properties of the global object
    >> at runtime rather than using pre-declared global variables.

    >
    > I'm not quite sure I understand. do you mean;
    >
    > function = argument() {
    > this.variable = "some value"
    > }


    No, that would be a syntax error. I meant a FunctionDeclaration, which
    is why I said that.

    > and pass that to the method call?


    Doing what?

    <snip>
    >> Why do this? Why create a new object with a - name - property
    >> and give it the value of the name property of the object passed
    >> in as an argument to the function call when you can just pass
    >> the argument object on to at this point?

    >
    > It was a demonstration to allow anyone interested to see the error...


    Not needlessly creating an extra object at that point would not have
    changes the error.

    >> 1. The cause of your error, as no argument is being sent to the
    >> Property constructor but it is treating its argument as if it was an
    >> object.

    >
    > Here it all starts to make sense, this is what I was after, the object
    > is created without the arguments. Yes, thanks... Now how to overcome
    > this.


    You overcome it by stopping doing it.

    >> 2. Pointless, as the call to this.super (where it has not resulted in a
    >> syntax error) will have added the - getName - method so masked the only
    >> public member of any Property instance created for the prototype.

    >
    > I don't understand.


    Every property that could be inherited from the prototype was assigned
    in the 'superclasses' constructor, so the object would have the
    properties directly assigned to it, and so the corresponding properties
    of the objects on the prototype chain would not be being used (so need
    not be there).

    >> 3. Stupid, because it is certainly not doing what it appears to be
    >> intended to do. When an object is constructed the assignment of the
    >> value of the constructor's prototype property to the new object's
    >> internal [[Prototoype]] property happens before the execution of the
    >> constructor's body code. Thus the first instantiation of an object with
    >> FormProperty will use the default - FormProperty.prototype - value as
    >> its [[Prototype]], the second instance will use the Property object
    >> created during the first instantiation, the third the Property object
    >> created during the second instantiation, and so on. If the prototype
    >> chain had any significance in the defining of any of these objects the
    >> fact that they would all have a different prototype, and particularly
    >> the fact that the first object's prototype was not an instance of the
    >> expected object, would destroy the likeness that is expected when
    >> implementing the 'class' concept in javascript.
    >>
    >> 4. Doubly stupid because the point of prototype inheritance it to have
    >> may object instances sharing the same prototype, and so sharing single
    >> function objects for its methods (where that is acceptable) and single
    >> default values for its properties. creating a second object with each
    >> object constructed is wasteful.

    >
    > > Where ever you are learning to write javascript like this is not a good
    > > source of information on the subject.

    >
    >
    > I got the code from
    > http://developer.mozilla.org/en/doc...e:The_Employee_Example:Creating_the_Hierarchy


    Oh no you didn't. You may have got a confused notion of one way in
    which javascript can parallel class hierarchies in Java but what
    appears on that page in no way suggests the code your wrote. There are,
    for example, no instances of a constructor's - prototype - property
    being set from inside a constructor.

    > which I would think is a reliable source....


    I would not be that optimistic, but if you don't understand what you
    are reading there its relative reliability becomes moot.

    > But would love to see your solution to this, allowing the base class to
    > be extended...


    But if I posted you code wouldn't I risk doing it to make myself feel
    good?

    Richard.
     
    Richard Cornford, Nov 13, 2006
    #10
  11. Pacific Fox

    VK Guest

    Pacific Fox wrote:
    > I've got a base object that works fine with named arguments when called
    > on it's own. However when I call the child object I get an error
    > "[associative array name] has no properties (in firefox)."
    >
    > I simple test:
    >
    > Property = function( arg ) {
    > /**
    > * Private properties
    > */
    > var name = arg.name; // required, the name of the field
    >
    > /**
    > * Priviliged methods, may be invoked publicly and may access private
    > variables
    > */
    > this.getName = function() {
    > return name;
    > }
    > };
    >
    > /**
    > * Class for form field properties, extends property
    > */
    > FormProperty = function( arg ) {
    > /**
    > * Inheritance
    > */
    > this.super = Property;
    > this.super( { name:arg.name } );
    > this.prototype = new Property;
    > }
    > //property = new FormProperty( { name:"myVar" } )
    > property = new Property( { name:"test" } )
    > alert( property.getName() );
    >
    > Un comment //property = new FormProperty( { name:"myVar" } )
    > to get the error.
    >
    > Thanks in advance for any help.


    You problem is that you mixing two types of constructors: object
    constructor (the most regular one) and constructor constructor
    (factory). In your code Property is a constructor factory returning new
    constructor instance - while you are trying to use it as a regular
    object constructor.

    <html>
    <head>
    <title>Checkboxes</title>
    <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-1">

    <script type="text/javascript">

    function Property() {
    return (
    function(arg) {
    var name = arg.name;
    this.getName = function() {
    return name;
    }
    });
    }

    function FormProperty(arg) {
    this.privProperty = new Property;
    this.privProperty( { name:arg.name } );
    }

    property = new FormProperty( { name:"myVar" } )
    alert( property.getName() );
    </script>

    </head>

    <body>
    </body>
    </html>
     
    VK, Nov 14, 2006
    #11
  12. VK wrote:
    > Pacific Fox wrote:
    >> I've got a base object that works fine with named arguments when called
    >> on it's own. However when I call the child object I get an error
    >> "[associative array name] has no properties (in firefox)."
    >>
    >> I simple test:
    >>
    >> Property = function( arg ) {
    >> /**
    >> * Private properties
    >> */
    >> var name = arg.name; // required, the name of the field
    >>
    >> /**
    >> * Priviliged methods, may be invoked publicly and may access
    >> private variables
    >> */
    >> this.getName = function() {
    >> return name;
    >> }
    >> };
    >>
    >> /**
    >> * Class for form field properties, extends property
    >> */
    >> FormProperty = function( arg ) {
    >> /**
    >> * Inheritance
    >> */
    >> this.super = Property;
    >> this.super( { name:arg.name } );
    >> this.prototype = new Property;
    >> }
    >> //property = new FormProperty( { name:"myVar" } )
    >> property = new Property( { name:"test" } )
    >> alert( property.getName() );
    >>
    >> Un comment //property = new FormProperty( { name:"myVar" } )
    >> to get the error.
    >>
    >> Thanks in advance for any help.

    >
    > You problem is that you mixing two types of constructors: object
    > constructor (the most regular one) and constructor constructor
    > (factory). In your code Property is a constructor factory returning new
    > constructor instance - while you are trying to use it as a regular
    > object constructor.


    You really do talk a lot of nonsense.

    <snip>
    > function Property() {
    > return (
    > function(arg) {
    > var name = arg.name;
    > this.getName = function() {
    > return name;
    > }
    > });
    > }
    >
    > function FormProperty(arg) {
    > this.privProperty = new Property;
    > this.privProperty( { name:arg.name } );
    > }

    <snip>

    The issue of 'subclassing' is inherent in the question; this rubbish is
    not only insanely designed but has also removed the Property 'class'
    (and any notion of 'subclassing') entirely.

    Richard.
     
    Richard Cornford, Nov 14, 2006
    #12
  13. Pacific Fox

    VK Guest

    > > You problem is that you mixing two types of constructors: object
    > > constructor (the most regular one) and constructor constructor
    > > (factory). In your code Property is a constructor factory returning new
    > > constructor instance - while you are trying to use it as a regular
    > > object constructor.


    > You really do talk a lot of nonsense.


    About the difference between
    1) constructor returning new object instances of some kind
    2) constructor returning constructor to produce new object instances of
    some kind
    ?

    That is not a "nonsense" but an important distinction.
    "A returns new instances of O; B returns new instance of A able to
    return new instances of O".
    In your opinion A and B do the same job?


    > <snip>
    > > function Property() {
    > > return (
    > > function(arg) {
    > > var name = arg.name;
    > > this.getName = function() {
    > > return name;
    > > }
    > > });
    > > }
    > >
    > > function FormProperty(arg) {
    > > this.privProperty = new Property;
    > > this.privProperty( { name:arg.name } );
    > > }

    > <snip>


    > The issue of 'subclassing' is inherent in the question; this rubbish is
    > not only insanely designed but has also removed the Property 'class'
    > (and any notion of 'subclassing') entirely.


    It seems that you did not understand what does the code do.
     
    VK, Nov 14, 2006
    #13
  14. VK wrote:
    >>> You problem is that you mixing two types of constructors: object
    >>> constructor (the most regular one) and constructor constructor
    >>> (factory). In your code Property is a constructor factory returning new
    >>> constructor instance - while you are trying to use it as a regular
    >>> object constructor.

    >
    > You really do talk a lot of nonsense.
    >
    > About the difference between
    > 1) constructor returning new object instances of some kind
    > 2) constructor returning constructor to produce new object instances of
    > some kind
    > ?


    There should be no "constructor" returning a constructor. If a function
    is to return a function (even if it is to be used as a constructor
    (which yours is not)) then it should not be called using the - new -
    operator, and should not be thought of, or spoken of, as a constructor.

    > That is not a "nonsense" but an important distinction.


    It is nonsense as soon as you start talking of "constructor returning
    constructor", and such talk may lead people to the even greater folly
    of applying the - new - operator to functions that are not being used
    to create object instances.

    > "A returns new instances of O; B returns new instance of A able to
    > return new instances of O".
    > In your opinion A and B do the same job?


    They are not both constructors.

    >> <snip>
    >>> function Property() {
    >>> return (
    >>> function(arg) {
    >>> var name = arg.name;
    >>> this.getName = function() {
    >>> return name;
    >>> }
    >>> });
    >>> }
    >>>
    >>> function FormProperty(arg) {
    >>> this.privProperty = new Property;
    >>> this.privProperty( { name:arg.name } );
    >>> }

    >> <snip>

    >
    >> The issue of 'subclassing' is inherent in the question; this rubbish is
    >> not only insanely designed but has also removed the Property 'class'
    >> (and any notion of 'subclassing') entirely.

    >
    > It seems that you did not understand what does the code do.


    Does it? Why do you think that then? Are you saying that your code does
    contain something that represents a means of creating Property
    instances? are you saying there is some reason for using the - new -
    operator with your - Property - function? Or that there is some point
    in having a reference to a function as - privProperty?

    If all is wanted is an ability to augment an object with a closure to
    store a name and a method for retreating it wouldn't:-

    function addNameInterface(name, obj){
    obj.getName = function(){
    return name;
    };
    }
    function FormProperty(arg) {
    addNameInterface(arg.name, this);
    }

    - get there quicker, cleaner, more directly and in a lot less code?

    Richard.
     
    Richard Cornford, Nov 14, 2006
    #14
  15. Pacific Fox

    VK Guest

    > There should be no "constructor" returning a constructor. If a function
    > is to return a function (even if it is to be used as a constructor
    > (which yours is not)) then it should not be called using the - new -
    > operator, and should not be thought of, or spoken of, as a constructor.


    Really? Says who? JavaScript function can be used as a simple function
    or as a constructor. That is it exactly can be defined at the moment
    of the call *only*. The very same function can be used in both ways. If
    it's called with "new" keyword then it acts as constructor, otherwise
    as a simple function. By just adding
    this.property = something;
    into function body you don't tranform it in some magic way into
    constructor.

    > > "A returns new instances of O; B returns new instance of A able to
    > > return new instances of O".
    > > In your opinion A and B do the same job?


    > They are not both constructors.


    They are: but they are constructing different things.

    > If all is wanted is an ability to augment an object with a closure to
    > store a name and a method for retreating it wouldn't:-
    >
    > function addNameInterface(name, obj){
    > obj.getName = function(){
    > return name;
    > };
    > }
    > function FormProperty(arg) {
    > addNameInterface(arg.name, this);
    > }
    >
    > - get there quicker, cleaner, more directly and in a lot less code?


    Mostly because it's not what OP was after :) If I'm mistaken OP will
    correct me.
     
    VK, Nov 14, 2006
    #15
  16. VK wrote:
    >> There should be no "constructor" returning a constructor. If a function
    >> is to return a function (even if it is to be used as a constructor
    >> (which yours is not)) then it should not be called using the - new -
    >> operator, and should not be thought of, or spoken of, as a constructor.

    >
    > Really? Says who? JavaScript function can be used as a simple function
    > or as a constructor.


    But there is no point in calling a function as a constructor (with the
    - new - operator) if it returns any object other than the value of the
    - this - keyword. Doing so just results in the creation of a
    superfluous object and then the throwing away of that object. There is
    no need for any other reason for never calling a function that returns
    any object other than - this - a constructor, or as a constructor. All
    the active effects of doing so would be achieved by just calling it as
    a function, and the useless side effects (and associated overheads) are
    then avoided, along with the conceptual misdirection following from the
    inappropriate use of the - new - operator.

    > That is it exactly can be defined at the moment
    > of the call *only*.


    And in English?

    > The very same function can be used in both ways.


    Not very effectively, and designing with such an intent would be
    perverse.

    > If it's called with "new" keyword then it acts as constructor,


    An object is created as a result, but if that object is never employed
    it becomes very questionable whether the function is acting as a
    constructor, or should be called as one.

    > otherwise as a simple function. By just adding
    > this.property = something;
    > into function body you don't tranform it in some magic way into
    > constructor.


    What is the "it" you are referring to?

    >>> "A returns new instances of O; B returns new instance of A able to
    >>> return new instances of O".
    >>> In your opinion A and B do the same job?

    >
    >> They are not both constructors.

    >
    > They are:


    No they are not. the latter may be categorised a 'factory' for
    constructor instances but it is not a constructor.

    > but they are constructing different things.
    >
    >> If all is wanted is an ability to augment an object with a closure to
    >> store a name and a method for retreating it wouldn't:-
    >>
    >> function addNameInterface(name, obj){
    >> obj.getName = function(){
    >> return name;
    >> };
    >> }
    >> function FormProperty(arg) {
    >> addNameInterface(arg.name, this);
    >> }
    >>
    >> - get there quicker, cleaner, more directly and in a lot less code?

    >
    > Mostly because it's not what OP was after :)


    I know the OP was not after that, it is a more sensible implementation
    of the nonsense code you posted. The OP is interested in subclassing,
    for which your code was irrelevant.

    > If I'm mistaken OP will
    > correct me.


    Richard.
     
    Richard Cornford, Nov 14, 2006
    #16
  17. Pacific Fox

    VK Guest

    Richard Cornford wrote:
    > But there is no point in calling a function as a constructor (with the
    > - new - operator) if it returns any object other than the value of the
    > - this - keyword.


    Really? Well, I guess it depends on the chosen coding style. The
    following code is polemic (to your statement) so a bit too complicated
    to show different options at once:

    <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-1">

    <script type="text/javascript">

    function F(arg) {

    if (typeof arg != 'string') {
    return new Boolean(false);
    }

    var secret = arg;

    this.secret = new Object;

    this.secret.getSecret = function() {
    window.alert(secret);
    }

    return this.secret;
    }

    var f0 = new F(null);
    var f1 = new F('foo');
    var f2 = new F('bar');

    if (f0 != false) {
    f0.getSecret();
    }

    if (f1 != false) {
    f1.getSecret();
    }

    if (f2 != false) {
    f2.getSecret();
    }
    </script>
    </head>

    <body>
    </body>
    </html>
     
    VK, Nov 14, 2006
    #17
  18. Pacific Fox

    VK Guest

    VK wrote:
    > The
    > following code is polemic (to your statement) so a bit too complicated
    > to show different options at once:


    or even like this:

    <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type" content="text/html;
    charset=iso-8859-1">
    <script>

    function F() {
    var $ = this;
    var private = 'empty'
    ;
    this.setPrivate = function(arg) {
    private = arg || 'empty';
    return $;
    }

    this.getPrivate = function() {
    return private;
    }
    }

    var f = (new F).setPrivate('foo');
    alert(f.getPrivate());
    </script>
    </head>

    <body>
    </body>
    </html>
     
    VK, Nov 14, 2006
    #18
  19. VK wrote:
    > Richard Cornford wrote:
    > > But there is no point in calling a function as a constructor (with the
    > > - new - operator) if it returns any object other than the value of the
    > > - this - keyword.

    >
    > Really? Well, I guess it depends on the chosen coding style.


    You can chose to program like a halfwit, if you must.

    > The following code is polemic (to your statement) so a bit too
    > complicated to show different options at once:

    <snip>
    > function F(arg) {
    >
    > if (typeof arg != 'string') {
    > return new Boolean(false);
    > }
    >
    > var secret = arg;
    >
    > this.secret = new Object;
    >
    > this.secret.getSecret = function() {
    > window.alert(secret);
    > }
    >
    > return this.secret;
    > }
    >
    > var f0 = new F(null);
    > var f1 = new F('foo');
    > var f2 = new F('bar');

    <snip>

    And once again you post code without stating what it is supposed to
    demonstrate. Presumably the intention was to show that there is some
    purpose in treating a function as a constructor when it does not return
    the object constructed. If so it fails to achieve that as substituting
    the above with:-

    function f(arg){
    if(typeof arg != 'string'){
    return new Boolean(false);
    }else{
    return ({getSecret:function(){alert(arg);}});
    }
    }

    var f0 = f(null);
    var f1 = f('foo');
    var f2 = f('bar');

    - achieves exactly the same outcome without treating a function that is
    not acting as a constructor as if it was a constructor (and again does
    so with considerably less code, and less convoluted code.

    There is no benefit to writing inefficient, indirect and confusing
    code, and being able to is hardly an excluse.

    Richard.
     
    Richard Cornford, Nov 14, 2006
    #19
  20. VK wrote:
    > VK wrote:
    >> The
    >> following code is polemic (to your statement) so a bit too
    >> complicated to show different options at once:

    >
    > or even like this:


    You blithering idiot: var f = (new F).setPrivate('foo'); _is_ calling a
    function that returns the - this - object as a constructor. It is not
    relevant to the question of whether functions that do not return the -
    this - object should be subject to the - new - operator.

    <snip>
    > function F() {
    > var $ = this;
    > var private = 'empty'
    > ;
    > this.setPrivate = function(arg) {
    > private = arg || 'empty';
    > return $;
    > }
    >
    > this.getPrivate = function() {
    > return private;
    > }
    > }


    Why the needless complexity?

    function F() {
    var private = 'empty' ;
    this.setPrivate = function(arg) {
    private = arg || private;
    return this;
    };
    this.getPrivate = function() {
    return private;
    };
    }

    - Does the same job.

    > var f = (new F).setPrivate('foo');


    What is the advantage of this indirect construct over the more normal:-

    var f = new F;
    f.setPrivate('foo');

    -or:-

    var f;
    (f = new F).setPrivate('foo)';

    - and not having to return the object instance from the - setPrivate -
    method (which should probably be returning an indicator of its success,
    if anything at all).

    Richard.
     
    Richard Cornford, Nov 14, 2006
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fuzzyman
    Replies:
    2
    Views:
    303
    Fuzzyman
    Feb 22, 2005
  2. Ramashish Baranwal

    Passing variable number of named arguments

    Ramashish Baranwal, Dec 27, 2006, in forum: Python
    Replies:
    2
    Views:
    273
    Ramashish Baranwal
    Dec 28, 2006
  3. Andrey Vul
    Replies:
    5
    Views:
    645
    Saeed Amrollahi
    Nov 4, 2009
  4. Roger Pack
    Replies:
    2
    Views:
    111
    Roger Pack
    Jan 4, 2010
  5. Christof Warlich

    named parameter idiom and inheritance

    Christof Warlich, Jun 14, 2012, in forum: C++
    Replies:
    8
    Views:
    677
    Alain Ketterlin
    Jun 17, 2012
Loading...

Share This Page