Very strange problem with Class object

Discussion in 'Javascript' started by Piotr K, Mar 30, 2008.

  1. Piotr K

    Piotr K Guest

    I simply ran out of ideas why this piece of code works so strange,
    it's a very simple class creating object:

    var Class = function(tpl) {
    return function() {
    for(var t in tpl) this[t] = tpl[t];
    };
    }

    var X = new Class({
    arr: []
    });

    var x = new X;
    x.arr.push(5);

    var y = new X;
    alert(y.arr[0]) // displays 5

    How, I mean HOW in the world it displays 5? I tested it with normal
    string and number variables - works fine, but I can't figure what's
    wrong with the arrays? I tried to change the Class function in many
    ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    nothing helped.. I'm frustrated, it's so freakin strange..

    Thanks for any help!
     
    Piotr K, Mar 30, 2008
    #1
    1. Advertising

  2. Piotr K

    VK Guest

    On Mar 31, 2:22 am, Piotr K <> wrote:
    > I simply ran out of ideas why this piece of code works so strange,
    > it's a very simple class creating object:
    >
    > var Class = function(tpl) {
    > return function() {
    > for(var t in tpl) this[t] = tpl[t];
    > };
    >
    > }
    >
    > var X = new Class({
    > arr: []
    >
    > });
    >
    > var x = new X;
    > x.arr.push(5);
    >
    > var y = new X;
    > alert(y.arr[0]) // displays 5
    >
    > How, I mean HOW in the world it displays 5? I tested it with normal
    > string and number variables - works fine, but I can't figure what's
    > wrong with the arrays? I tried to change the Class function in many
    > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > nothing helped.. I'm frustrated, it's so freakin strange..


    Because you have created a very efficient memory leak over closure
    with tpl value retained in it. I honestly have no idea what does this
    code suppose to mean. Is it some work-on-denial test for a script
    engine? There are more sophisticated professional packages for that,
    Acid 3 from the first coming into my mind.
     
    VK, Mar 30, 2008
    #2
    1. Advertising

  3. Piotr K

    Piotr K Guest

    On 31 Mar, 00:39, VK <> wrote:
    > On Mar 31, 2:22 am, Piotr K <> wrote:
    >
    >
    >
    > > I simply ran out of ideas why this piece of code works so strange,
    > > it's a very simple class creating object:

    >
    > > var Class = function(tpl) {
    > > return function() {
    > > for(var t in tpl) this[t] = tpl[t];
    > > };

    >
    > > }

    >
    > > var X = new Class({
    > > arr: []

    >
    > > });

    >
    > > var x = new X;
    > > x.arr.push(5);

    >
    > > var y = new X;
    > > alert(y.arr[0]) // displays 5

    >
    > > How, I mean HOW in the world it displays 5? I tested it with normal
    > > string and number variables - works fine, but I can't figure what's
    > > wrong with the arrays? I tried to change the Class function in many
    > > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > > nothing helped.. I'm frustrated, it's so freakin strange..

    >
    > Because you have created a very efficient memory leak over closure
    > with tpl value retained in it. I honestly have no idea what does this
    > code suppose to mean. Is it some work-on-denial test for a script
    > engine? There are more sophisticated professional packages for that,
    > Acid 3 from the first coming into my mind.


    It creates classes, the same way that ie. mooTools does, I just
    shortened it for clarity.. however, I managed to solve my problem ;)
    btw. mooTools Class suffers from the same problem which kind a
    suprised me
     
    Piotr K, Mar 30, 2008
    #3
  4. Piotr K

    VK Guest

    On Mar 31, 2:53 am, Piotr K <> wrote:
    > On 31 Mar, 00:39, VK <> wrote:
    >
    >
    >
    > > On Mar 31, 2:22 am, Piotr K <> wrote:

    >
    > > > I simply ran out of ideas why this piece of code works so strange,
    > > > it's a very simple class creating object:

    >
    > > > var Class = function(tpl) {
    > > > return function() {
    > > > for(var t in tpl) this[t] = tpl[t];
    > > > };

    >
    > > > }

    >
    > > > var X = new Class({
    > > > arr: []

    >
    > > > });

    >
    > > > var x = new X;
    > > > x.arr.push(5);

    >
    > > > var y = new X;
    > > > alert(y.arr[0]) // displays 5

    >
    > > > How, I mean HOW in the world it displays 5? I tested it with normal
    > > > string and number variables - works fine, but I can't figure what's
    > > > wrong with the arrays? I tried to change the Class function in many
    > > > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > > > nothing helped.. I'm frustrated, it's so freakin strange..

    >
    > > Because you have created a very efficient memory leak over closure
    > > with tpl value retained in it. I honestly have no idea what does this
    > > code suppose to mean. Is it some work-on-denial test for a script
    > > engine? There are more sophisticated professional packages for that,
    > > Acid 3 from the first coming into my mind.

    >
    > It creates classes, the same way that ie. mooTools does, I just
    > shortened it for clarity.. however, I managed to solve my problem ;)


    You did? OK, enjoy your program working with a memory monitor.

    > btw. mooTools Class suffers from the same problem which kind a
    > suprised me.


    You mean mooTools cut a deal with the Spirit of Programming so memory
    leaks and closures should not be applicable to it no matter how bad
    the code is? :) :-|

    My heart is bleeding by looking at this code. Maybe you could take
    Prototype.js and its pattern instead? It still imitating class-based
    paradigm but it has some respect to the real nature of the used
    language so it does not leak 1Mb per 50Kb of code.

    Up to you, anyway.
     
    VK, Mar 31, 2008
    #4
  5. Piotr K

    Piotr K Guest

    On 31 Mar, 01:09, VK <> wrote:
    > On Mar 31, 2:53 am, Piotr K <> wrote:
    >
    >
    >
    > > On 31 Mar, 00:39, VK <> wrote:

    >
    > > > On Mar 31, 2:22 am, Piotr K <> wrote:

    >
    > > > > I simply ran out of ideas why this piece of code works so strange,
    > > > > it's a very simple class creating object:

    >
    > > > > var Class = function(tpl) {
    > > > > return function() {
    > > > > for(var t in tpl) this[t] = tpl[t];
    > > > > };

    >
    > > > > }

    >
    > > > > var X = new Class({
    > > > > arr: []

    >
    > > > > });

    >
    > > > > var x = new X;
    > > > > x.arr.push(5);

    >
    > > > > var y = new X;
    > > > > alert(y.arr[0]) // displays 5

    >
    > > > > How, I mean HOW in the world it displays 5? I tested it with normal
    > > > > string and number variables - works fine, but I can't figure what's
    > > > > wrong with the arrays? I tried to change the Class function in many
    > > > > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > > > > nothing helped.. I'm frustrated, it's so freakin strange..

    >
    > > > Because you have created a very efficient memory leak over closure
    > > > with tpl value retained in it. I honestly have no idea what does this
    > > > code suppose to mean. Is it some work-on-denial test for a script
    > > > engine? There are more sophisticated professional packages for that,
    > > > Acid 3 from the first coming into my mind.

    >
    > > It creates classes, the same way that ie. mooTools does, I just
    > > shortened it for clarity.. however, I managed to solve my problem ;)

    >
    > You did? OK, enjoy your program working with a memory monitor.
    >
    > > btw. mooTools Class suffers from the same problem which kind a
    > > suprised me.

    >
    > You mean mooTools cut a deal with the Spirit of Programming so memory
    > leaks and closures should not be applicable to it no matter how bad
    > the code is? :) :-|
    >
    > My heart is bleeding by looking at this code. Maybe you could take
    > Prototype.js and its pattern instead? It still imitating class-based
    > paradigm but it has some respect to the real nature of the used
    > language so it does not leak 1Mb per 50Kb of code.
    >
    > Up to you, anyway.


    Ups, my mistake, they made it a little diffrent - rather than coping
    all attributes they assign them to returned function prototype. So
    after change the Class look like this:

    var Class = function(tpl) {
    var f = function() {
    }

    f.prototype = tpl;
    f.constructor = Class;
    return f;
    }

    I guess this is memory-leek free? :)
     
    Piotr K, Mar 31, 2008
    #5
  6. Piotr K wrote:
    >I simply ran out of ideas why this piece of code works so strange,
    > it's a very simple class creating object:
    >
    > var Class = function(tpl) {
    > return function() {
    > for(var t in tpl) this[t] = tpl[t];
    > };
    > }
    >
    > var X = new Class({
    > arr: []
    > });
    >
    > var x = new X;
    > x.arr.push(5);
    >
    > var y = new X;
    > alert(y.arr[0]) // displays 5
    >
    > How, I mean HOW in the world it displays 5?


    You assign a reference to an array to its 'arr' property when your
    create your - x - object and then assign a reference to the same array
    to the 'arr' property of your - y - object when your create that. Then
    when you push an element onto that array it is a member of the array
    referred to as - x.arr - and - y.arr -.

    > I tested it with normal
    > string and number variables - works fine,


    Using - push - on an array is modifying that array. There are no
    operations in javascript that are capable of modifying a primitive
    value, so you could not be doing the equivalent to a string or a number.

    > but I can't figure what's wrong with the arrays?


    What is wrong is that you are expecting each object instance to have its
    own array instance but you have programmed them to share a single array
    instance.

    > I tried to change the Class function in many
    > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > nothing helped.. I'm frustrated, it's so freakin strange..


    function X(){
    this.arr = [];
    }

    var x = new X;
    x.arr.push(5);

    var y = new X;
    alert(y.arr[0]) // displays undefined

    Don't over-complicate things.

    > Thanks for any help!


    It is best to disregard anything that VK says as he has no idea what his
    own cod actually does let alone anyone else's. Earlier in the week he
    posted:-

    | <script type="text/javascript">
    | (function(){
    | var name = 'doc02';
    | document.write(''.concat(
    | '<iframe name="',name,'" ',
    | 'src="',getUrlForIframe(name),'" ',
    | 'onload="',
    | '(function(){',
    | 'var n = \'',name,'\';',
    | 'var win = self.frames[n];',
    | 'var doc = win.document;',
    | 'if ((doc) && (\'designMode\' in doc)) {',
    | ' doc.designMode = \'on\';',
    | '}','})();"'));
    | window.alert('Fine up to this point');
    | })();
    | window.alert('getUrlForIframe is ' + typeof getUrlForIframe);
    | window.setTimeout('window.alert(true)',1000);
    | </script>

    - which is insane, and if you asked him to explain that - onload -
    attribute he either could not or would post a nonsense explanation.

    Richard.
     
    Richard Cornford, Mar 31, 2008
    #6
  7. Piotr K wrote:
    > It creates classes,


    It does not. It cannot, since current client-side implementations do not
    support classes but use prototype-based inheritance instead. The sooner you
    understand this, the sooner you are running the chance of writing efficient
    and easily maintainable ECMAScript-compliant programs.

    > the same way that ie. mooTools does,


    Bad (and worse) code written by other clueless people does not justify bad
    code on your part. It is that fundamental design flaw that makes many
    client-side script libraries useless in a wider Web context, especially in
    conjunction with other libraries; particularly MooTools here because it
    follows several of the mindboggingly stupid design patterns of the
    Prototype.js junk.

    You will be best off ignoring VK, the resident fairytale-teller, when it
    comes to any sort of technical advice; or you should take everything they
    say with a handful (two? a box?) of salt.


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
     
    Thomas 'PointedEars' Lahn, Mar 31, 2008
    #7
  8. Piotr K <> writes:

    > Ups, my mistake, they made it a little diffrent - rather than coping
    > all attributes they assign them to returned function prototype. So
    > after change the Class look like this:
    >
    > var Class = function(tpl) {
    > var f = function() {
    > }
    >
    > f.prototype = tpl;
    > f.constructor = Class;


    This line doesn't really do anything (unless the rest of the library
    it is contained in uses the constructor property).
    I would expect the following instead:
    tpl.constructor = f;

    > return f;
    > }


    The will still have the same problem as your original program:
    var myClass = Class({arr:[]});
    var x = new myClass();
    var y = new myClass();
    will share the same array instance as x.arr and y.arr. You only ever
    create one array (the "[]" array literal), so the instances will have
    to share.

    > I guess this is memory-leek free? :)


    I have no idea what memory leak we are talking about. The original
    version had no memory leak that I could see.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Mar 31, 2008
    #8
  9. Piotr K

    VK Guest

    On Mar 31, 3:09 am, VK <> wrote:
    > On Mar 31, 2:53 am, Piotr K <> wrote:
    >
    >
    >
    > > On 31 Mar, 00:39, VK <> wrote:

    >
    > > > On Mar 31, 2:22 am, Piotr K <> wrote:

    >
    > > > > I simply ran out of ideas why this piece of code works so strange,
    > > > > it's a very simple class creating object:

    >
    > > > > var Class = function(tpl) {
    > > > > return function() {
    > > > > for(var t in tpl) this[t] = tpl[t];
    > > > > };

    >
    > > > > }

    >
    > > > > var X = new Class({
    > > > > arr: []

    >
    > > > > });

    >
    > > > > var x = new X;
    > > > > x.arr.push(5);

    >
    > > > > var y = new X;
    > > > > alert(y.arr[0]) // displays 5

    >
    > > > > How, I mean HOW in the world it displays 5? I tested it with normal
    > > > > string and number variables - works fine, but I can't figure what's
    > > > > wrong with the arrays? I tried to change the Class function in many
    > > > > ways like making "new Object(tpl[t])" or "tpl[t].valueOf()" but
    > > > > nothing helped.. I'm frustrated, it's so freakin strange..

    >
    > > > Because you have created a very efficient memory leak over closure
    > > > with tpl value retained in it. I honestly have no idea what does this
    > > > code suppose to mean. Is it some work-on-denial test for a script
    > > > engine? There are more sophisticated professional packages for that,
    > > > Acid 3 from the first coming into my mind.


    Maybe I should be more detailed. What you have originally posted is a
    version of mutable anonymous constructor. This sick invention of some
    Perl OOP traumatized programmer got in big fashion last year for some
    reason: lucky by now this madness gets lesser and lesser popular. Do
    do not be distracted by side issues, let's us take a mutable anonymous
    constructor in its most simple form (comments are below the HTML):

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html lang="en-US">
    <head>
    <meta http-equiv="Content-type"
    content="text/html; charset=iso-8859-1">
    <title>Demo</title>
    <script type="text/javascript">

    function Parent(outer_arg) {
    return function(inner_arg) {
    this['foo'] = outer_arg;
    this['bar'] = inner_arg;
    }
    }

    var Child = new Parent('foo');

    var a = new Child('bar_a');

    var b = new Child('bar_b');

    var c = new Child('bar_c');

    window.alert(a.foo==b.foo && b.foo==c.foo && c.foo=='foo'); // true

    window.alert(a.bar); // 'bar_a'

    window.alert(b.bar); // 'bar_b'

    window.alert(c.bar); // 'bar_c'

    </script>
    </head>
    <body>
    <p>No content</p>
    </body>
    </html>

    So what we have got here:

    1) Parent creates Child and provides closure for Child. Grace to it on
    each call Child has access to Parent context including outer_arg. This
    is where in your sample the "mysterious" 5 value comes out.
    2) Child constructor creates instances with per-instance properties.
    Because Parent and Child are neither in class nor prototype
    inheritance relations, I would say that 2007 was the year of birth of
    all new "closure-based inheritance".
    Once I tried to get an answer from one CS specialist what all these
    mutable anonymous constructors - or closure-based inheritance or name
    it as you want - is good for. With a light in he eyes he explained
    that it allows to get all different instances from the same class
    which are not in OOP relations with each other. Maybe I did not get
    him right, or maybe he already got too much of Californian sun, or I
    did, or both us. Any way.
     
    VK, Mar 31, 2008
    #9
    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. brewman
    Replies:
    0
    Views:
    1,468
    brewman
    Aug 28, 2003
  2. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    518
    Raymond Hettinger
    Jul 27, 2003
  3. Kenneth McDonald

    Very, very strange problem with properties

    Kenneth McDonald, May 4, 2004, in forum: Python
    Replies:
    2
    Views:
    277
    Kenneth McDonald
    May 4, 2004
  4. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,719
    Merrill & Michele
    Oct 19, 2004
  5. Abhishek Jha

    very very very long integer

    Abhishek Jha, Oct 16, 2004, in forum: C Programming
    Replies:
    4
    Views:
    468
    jacob navia
    Oct 17, 2004
Loading...

Share This Page