Object oriented stuff and browsers related thing

Discussion in 'Javascript' started by Luke Matuszewski, Nov 18, 2005.

  1. Here are some questions that i am interested about and wanted to here
    an explanation/discussion:
    1. (general) Is the objectness in JavaScript was supported from the
    very first version of it (in browsers) ? What about the new syntax of
    creating a object using { 'propName1':'propValue1',
    'propName2':'propValue2', 'propName3':{ /* another object */ } } - from
    what version of JScript/JavaScript it was supported (from what browsers
    versions) ?

    2. (object-oriented) Every object has a prototype (and so on the
    toString(), (other)... methods inherited from it). When i do sth like
    this:

    function MyConstr() {
    var thisVar = this; /* Protected pattern */
    var someProtected = 3; /* Protected pattern */
    var this.thisVar = this; /* Public pattern */
    /* here 'this' specifies the reference to the created object via 'new'
    keyword */
    this.myFunc = function () { /* Privilaged pattern */
    /* here 'this' specifies the reference to ... what ?
    1. to function myFunc context - so it points no more to the newly
    created object via new MyConstr()
    (thus someone could say it is buggy and should use thisVar)
    2. to newly created object via new MyConstr();
    */

    }

    }

    MyConstr.myFunc2 = function () { /* Public pattern */
    /* here 'this' specifies the reference to ... what ?
    1. to function myFunc2 context - so it points no more to the newly
    created object via new MyConstr()
    (thus someone could say it is buggy and should use this.thisVar)
    2. to newly created object via new MyConstr();
    */
    }

    MyConstr.prototype.myFunc3 = function () {
    /* here 'this' references to what object/contex ?
    */
    }

    Questions:
    2.1 What is the difference between the myFunc and myFunc2 ? I know that
    inserting function inside constructor takes more memory when
    instantiating new objects than outside like myFunc2... but myFunc has
    acces to someProtected variable and myFunc2 does not. Can anyone point
    other differences ?
    2.2 What about the issues with 'this' keyword ? (see more comments
    about it in source code provided above - especially concerning about
    what object/contex 'this' references)
    2.3 Properties added outside the constructor body are accessible
    without first creating an object right ? so one could say they are
    static... is this correct ? (any other issues).
    2.4 Any other suggestions on OOP in JS ? please write sth or provide a
    link (i have read faq_notes on jiberring).

    3. I have heard that statement
    MyConstr.myFunc2 = function ()
    was bad supported in IE5 ? (or maybe a new Function(...) construction).
    Please provied a link/comment ?

    Thats all i remember folks :)
    Waitin for reply.
     
    Luke Matuszewski, Nov 18, 2005
    #1
    1. Advertising

  2. Ok i have done some testing and i want to here am i right:
    1. Constructors can be called like functions and when they are the
    'this' keyword points to global object or 'outer' this in terms of
    [[scope]] chain (so points to outer object when called inside living
    object);
    In functions assigned to constructor outside like:
    MyArray.myFunc = function () {
    this.d = "Wow";
    }
    'this' keyword points to MyArray context, so MyArray.d is "Wow".
    (so shortly 'this' points to 'nearest' object in scope chain of
    execution contexts, here we see that for myFunc function 'nearest'
    object is in MyArray object (which is function object).

    2. Keyword 'this' in constructor points to object created via 'new'
    keyword (and here are some remarks that this should be put in some
    variable - like thisRef (var thisRef = this;) for accessing 'this' in
    functions avoiding some buggs in some browsers - like early IE);

    3. Keyword 'this' in function added to prototype point to prototype
    object so doing:
    MyArray.prototype.myFunc3 = function () {
    this.protoMy = 5;
    }
    , and then invoking
    MyArray.prototype.myFunc3()
    'this' points to prototype object (which is, when not touched, the pure
    Object).
    This prototype object assigned to constructor is shared among other
    newly (via 'new') created objects, so changing its properties later
    will affect all object created before and after changes of it.
    If you assign new object to prototype then objects created before will
    not be affected and only newly created objects will have new prototype
    object (here we feel that in JavaScript we deal with references and
    primitives).

    I have also tried to do smt like this:
    MyArray.prototype = 3; /* this is probably an error, but it assigns
    properly the value 3 */
    MyArray.prototype.myFunc3 = function () {
    this.protoMy = 5;
    }
    , then new objects are created but with 'standard' prototype (which is
    Object... without myFunc3).
    var myArray1 = new MyArray();
    .... some other checks
    typeof(myArray1.prototype) == undefined; /* so objects doesn't have
    named property 'prototype' */
    typeof(MyArray) == function;
    typeof(MyArray1) == object;

    If objects doesn't have named property 'prototype' so they 'use'
    prototype of its constructor.

    This is all i figured, any suggestions/comments ?
    Please reply.
    Best regards.
     
    Luke Matuszewski, Nov 18, 2005
    #2
    1. Advertising

  3. Luke Matuszewski wrote:

    > Here are some questions that i am interested about and wanted to here
    > an explanation/discussion:
    > 1. (general) Is the objectness in JavaScript was supported from the
    > very first version of it (in browsers) ?


    Yes, with Netscape 2.0 being the first (and only) browser to support
    JavaScript 1.0. It is also supported since JScript 1.0 and specified
    since ECMAScript Edition 1.

    JavaScript < 2/JScript < 7/ECMAScript are object-oriented programming
    languages using prototype-based inheritance.

    JavaScript 2/JScript 7 (.NET)/ECMAScript 4 are object-oriented programming
    languages supporting both prototype-based and class-based inheritance.
    (However, there are only proposals and test implementations of those for
    the first and the last yet.)

    > What about the new syntax of
    > creating a object using { 'propName1':'propValue1',
    > 'propName2':'propValue2', 'propName3':{ /* another object */ } } - from
    > what version of JScript/JavaScript it was supported (from what browsers
    > versions) ?


    Documentation (see e.g. <URL:http://jibbering.com/faq/>,
    <URL:http://mozilla.org/js/language/>,
    <URL:http://developer.mozilla.org/javascript/>
    and
    <URL:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/jscript7/html/jslrfjscriptlanguagereference.asp>)
    states that such Object (object) literals are supported from

    JavaScript version 1.3 (NN 4.06, Mozilla/5.0),
    JScript version 3.0 (IE/Win 4+, IIS 4+),
    ECMAScript Edition 3

    on. The same goes for Array (object) literals: [..., ...].

    Now that you mentioned it: Since I asked such questions myself often and
    finally did not want to bother checking all references every time, I have
    begun to create a support matrix on my local Web server and now have
    uploaded the latest version of it to be accessible at

    <http://www.PointedEars.de/scripts/js-version-info>

    I intend to correct/complete it with the help of further tests,
    documentation and posters of this group. (If the scrolling table
    is garbled in Firefox, just increase text size via the View menu
    or Ctrl++ and decrease it again (with Ctrl+-). That is a Firefox
    bug I was willing to accept for local use.)

    > 2. (object-oriented) Every object has a prototype (and so on the
    > toString(), (other)... methods inherited from it). When i do sth
    > like this:
    >
    > function MyConstr() {
    > var thisVar = this; /* Protected pattern */
    > var someProtected = 3; /* Protected pattern */
    > var this.thisVar = this; /* Public pattern */

    ^^^^^^^^^
    This (*g*) is a syntax error. It should be

    this.thisVar = this; /* Public pattern */

    > /* here 'this' specifies the reference to the created object via 'new'
    > keyword */


    True, iff MyConstr() is called as a constructor (with the NewExpression).

    > this.myFunc = function () { /* Privilaged pattern */
    > /* here 'this' specifies the reference to ... what ?
    > 1. to function myFunc context - so it points no more to the newly
    > created object via new MyConstr()
    > (thus someone could say it is buggy and should use thisVar)
    > 2. to newly created object via new MyConstr();
    > */


    2., unless Function.prototype.call() is used. But if you referred to `this'
    as within the method definition, that would not be 2. because it is within
    the constructor, but because the method is that of what will be the calling
    object.

    > }
    >
    > }
    >
    > MyConstr.myFunc2 = function () { /* Public pattern */
    > /* here 'this' specifies the reference to ... what ?
    > 1. to function myFunc2 context - so it points no more to the newly
    > created object via new MyConstr()
    > (thus someone could say it is buggy and should use this.thisVar)
    > 2. to newly created object via new MyConstr();
    > */
    > }


    Neither one. It refers to `MyConstr' as that would be the
    calling object, unless Function.prototype.call() is used.

    > MyConstr.prototype.myFunc3 = function () {
    > /* here 'this' references to what object/contex ?
    > */
    > }


    `this' refers to the object that `MyConstr' is the constructor of or that
    is derived from `MyConstr', unless Function.prototype.call() is used. So
    it refers to the calling object again.

    > Questions:
    > 2.1 What is the difference between the myFunc and myFunc2 ? I know that
    > inserting function inside constructor takes more memory when
    > instantiating new objects than outside like myFunc2... but myFunc has
    > acces to someProtected variable and myFunc2 does not. Can anyone point
    > other differences ?


    I think we have clarified this about 15 minutes before your posting
    in <URL:news:>.
    Since it was posted via Google Groups, it should already be archived
    there.

    > 2.2 What about the issues with 'this' keyword ? (see more comments
    > about it in source code provided above - especially concerning about
    > what object/contex 'this' references)


    It refers to the calling or created object or to the Global Object
    if there is none of the former.

    > 2.3 Properties added outside the constructor body are accessible
    > without first creating an object right ? so one could say they are
    > static... is this correct ? (any other issues).


    Correct.

    > 2.4 Any other suggestions on OOP in JS ? please write sth or provide a
    > link (i have read faq_notes on jiberring).


    For example <URL:http://crockford.com/javascript/javascript.html> pp.

    > 3. I have heard that statement
    > MyConstr.myFunc2 = function ()
    > was bad supported in IE5 ? (or maybe a new Function(...) construction).
    > Please provied a link/comment ?


    The function operator (first line) is documented to be supported from

    JavaScript version 1.5 (see above; however it works in NN 4.8 as well)
    JScript ?
    ECMAScript Edition 3

    on. The Function constructor (second line) is documented to be supported
    from

    JavaScript version 1.1 (NN 3.0, NES 2.0)
    JScript version 2.0 (IE/Win 3, IIS 3)
    ECMAScript Edition 1

    on.


    HTH

    PointedEars
     
    Thomas 'PointedEars' Lahn, Nov 19, 2005
    #3
  4. On 18/11/2005 18:05, Luke Matuszewski wrote:

    [snip]

    > 1. (general) Is the objectness in JavaScript was supported from the
    > very first version of it (in browsers) ?


    Yes, though that's irrelevant. It would be rare enough to come across a
    client implementing only JavaScript 1.3 (and its equivalents), let alone
    1.0.

    > What about the new [object literal] syntax [...]


    It isn't new. Again, don't worry about it. Any browser that old is
    unlikely to provide an object model worth scripting.

    [snip]

    > function MyConstr() {
    > var thisVar = this; /* Protected pattern */
    > var someProtected = 3; /* Protected pattern */
    > var this.thisVar = this; /* Public pattern */


    That last statement will throw a run-time exception. A var statement is
    a comma-separated list of identifiers, with optional initialisers. A
    full-stop (.) is not allowed in an identifier. You meant

    this.thisVar = this;

    though that's entirely redundant.

    [snip]

    > this.myFunc = function () { /* Privilaged pattern */
    > /* here 'this' specifies the reference to ... what ?


    The value of the this operator, in the context of functions, varies
    depending on the way in which a function is called.

    If a function is called using a member expression (that is, as a
    property of some object), the this operator will reference its object:

    object.myMethod(); /* this = object */

    Any function called /directly/ will have a this value that refers to the
    global object, even if that function was the property of another object:

    var myMethod = object.myMethod;

    function myFunction() {}

    myMethod(); /* In both cases,
    myFunction(); * this = global object
    */

    Finally, a script may provide a custom object using the built-in
    Function.prototype.call or apply methods:

    myMethod.call(object); /* Identical to first example */
    myMethod.call(anotherObject); /* this = anotherObject */

    However, it should be noted that JScript doesn't implement these methods
    until version 5.5 (though they can be emulated, if need be).

    There are a couple of important implications here if one extends these
    ideas further. The first involves transferring methods from one object
    to another:

    function A() {}
    A.prototype.myMethod = function() {};
    function B() {}

    var a = new A(),
    b = new B();

    b.myMethod = a.myMethod;

    At this point, 'b' has a reference to a method that previously belonged
    to 'a'. Calling that method through 'b'

    b.myMethod();

    means that the this operator will refer to 'b', not 'a'.

    This is of interest when trying to use object methods as event
    listeners. Assigning a method to an element as an event listener
    produces precisely the same effect as that above.

    Another consequence involves private instance methods:

    function MyObject() {
    function privateMethod() {}

    this.publicMethod = function() {
    privateMethod();
    };
    }

    When publicMethod calls privateMethod, the this operator will refer to
    the global object meaning that privateMethod (as is) cannot access any
    public properties.

    One solution, and potentially the nicest, would be to use the call
    method in publicMethod and pass the this operator as its first argument.
    The this operator in privateMethod would then refer to the object
    instance as well. However, as I noted above, previous versions of
    JScript in IE don't implement it, so the next best thing is to create a
    private instance member, which private methods can access, that
    references the object. The first thisVar member in the code posted is an
    example.

    function MyObject() {
    var self = this;

    function privateMethod() {
    /* Use self to refer to public
    * properties of this instance.
    */
    }

    this.publicMethod = function() {
    privateMethod();
    };
    }

    [snip]

    > MyConstr.myFunc2 = function () { /* Public pattern */
    > /* here 'this' specifies the reference to ... what ?


    The same behaviour described above also applies here. However, the
    method in this instance is static: a property of the constructor itself,
    not any instance.

    var object = new MyConstr();

    MyConstr.myFunc2(); /* OK */
    object.myFunc2(); /* myFunc2 undefined -> Run-time error */

    [snip]

    > MyConstr.prototype.myFunc3 = function () {
    > /* here 'this' references to what object/contex ?


    Again, the same behaviour will be observed, but this situation is closer
    to the first approach.

    There are two key differences between adding methods in the constructor
    and via the prototype object.

    1. Privileged methods that access private instance members can
    only be created within the context of the constructor
    function.

    function MyObject() {
    var privateMember = 'private instance';

    this.privilegedMethod = function() {
    return privateMember;
    };
    }
    MyObject.prototype.prototypedMethod = function() {
    return privateMember;
    };

    var o = new MyObject();

    o.privilegedMethod(); /* 'private instance' */
    o.prototypedMethod(); /* [run-time error] */

    Prototyped methods can be used to access private static
    methods, though:

    var MyObject = (function() {
    var staticMember = 'private static';

    /* This function is the actual constructor function
    * used to create MyObject instances. It is returned
    * later so that other code can access, and call, it.
    *
    * A function expression (above) wraps around this
    * constructor and the private static member, creating
    * a separate execution context in which to store these
    * variables.
    */
    function constructor() {
    var privateMember = 'private instance';

    this.constructorMethod = function() {
    /* ... */
    };
    }
    constructor.prototype.prototypedMethod = function() {
    /* ... */
    };
    return constructor;
    })();

    MyObject.prototype.unprivilegedMethod = function() {
    /* ... */
    };

    In this example, instances created from the MyObject
    constructor function will have three public methods:
    constructorMethod, prototypedMethod, and unprivilegedMethod.
    The first, constructorMethod, has access to both the
    privateMember and staticMember variables. The second,
    prototypedMethod, has access to the staticMember variable.
    Finally, unprivilegedMethod has access to none of them. It
    will only be able to access public members.

    2. Prototyped methods are shared by all instances of an object,
    whereas methods created by a function expression and
    assigned in the constructor are created anew with each
    instance.

    If a prototyped method modifies a variable in its scope
    chain, all instances will use that modified value later.
    This isn't necessarily a bad thing - it's precisely how the
    private static example works - but it should be remembered.

    [snip]

    > 2.1 What is the difference between the myFunc and myFunc2 ?


    Hopefully, you'll considered that answered already: myFunc is an
    instance method, and myFunc2 is a static method.

    > I know that inserting function inside constructor takes more memory when
    > instantiating new objects than outside like myFunc2...


    It also takes longer as the function expression has to be evaluated each
    time.

    [snip]

    > 3. I have heard that statement
    > MyConstr.myFunc2 = function ()
    > was bad supported in IE5 ? (or maybe a new Function(...) construction).
    > Please provied a link/comment ?


    I can't say that I've noticed any problems.

    [snip]

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
     
    Michael Winter, Nov 20, 2005
    #4
  5. On 18/11/2005 23:25, Luke Matuszewski wrote:

    [snip]

    > 1. Constructors can be called like functions


    Constructors /are/ functions, though they're not often written in a way
    that allows them to be called normally with useful results.

    When the new operator is used, the constructor will eventually be
    called. However, an object is first created, the prototype property of
    the constructor forms the prototype chain, and this new object is used
    for the this operator. When the constructor returns, the object is the
    result of the new operator unless the constructor returns its own object
    (which is used instead).

    > and when they are the 'this' keyword points to global object


    If called directly, yes. See my other post, if you haven't yet.

    > or 'outer' this in terms of [[scope]] chain (so points to outer
    > object when called inside living object);


    I'm not sure what point you're trying to make here, so I can't say
    whether it's right or not.

    > In functions assigned to constructor outside like:
    > MyArray.myFunc = function () {
    > this.d = "Wow";
    > }
    > 'this' keyword points to MyArray context


    "MyArray context"? Again, you seem to be using terms that are confusing
    the issue.

    If the myFunc method is called thus:

    MyArray.myFunc();

    then the this operator will refer to MyArray.

    > so MyArray.d is "Wow".


    Yes.

    > (so shortly 'this' points to 'nearest' object in scope chain of
    > execution contexts, here we see that for myFunc function 'nearest'
    > object is in MyArray object (which is function object).


    No. The this operator has nothing to do with the scope chain. When
    considering functions, it's value is determined entirely by how the
    function is called.

    > 2. Keyword 'this' in constructor points to object created via 'new'
    > keyword (and here are some remarks that this should be put in some
    > variable - like thisRef (var thisRef = this;) for accessing 'this' in
    > functions avoiding some buggs in some browsers - like early IE);


    There is a bug in IE's event model regarding the this operator and the
    attachEvent method, but none, as I recall, with its object model.

    > 3. Keyword 'this' in function added to prototype point to prototype
    > object so doing:
    > MyArray.prototype.myFunc3 = function () {
    > this.protoMy = 5;
    > }
    > , and then invoking
    > MyArray.prototype.myFunc3()
    > 'this' points to prototype object (which is, when not touched, the pure
    > Object).


    Correct.

    > This prototype object assigned to constructor is shared among other
    > newly (via 'new') created objects, so changing its properties later
    > will affect all object created before and after changes of it.


    Correct.

    When an object is created, the prototype property of the constructor is
    copied to the internal [[prototype]] property of the object (if the
    prototype property is an object). As this copied value is a reference,
    both the prototype property and internal [[prototype]] property will
    refer to the same object. If the properties of that object are modified,
    both previously instantiated and newly instantiated objects will be
    affected.

    > If you assign new object to prototype then objects created before will
    > not be affected and only newly created objects will have new prototype
    > object [...]


    Yes. The prototype property and the internal [[prototype]] properties of
    previously instantiated objects will now refer to different objects.
    Altering the properties of one will not affect the other.

    [snip]

    > I have also tried to do smt like this:
    > MyArray.prototype = 3; /* this is probably an error, but it assigns
    > properly the value 3 */


    It's not an error, but it won't react properly because the prototype
    property is now a number value, not an object.

    MyArray.prototype = new Number(3);

    is a different matter.

    > MyArray.prototype.myFunc3 = function () {
    > this.protoMy = 5;
    > }


    As the prototype property from your code above is not an object, you
    cannot add properties to it. So, the number value will temporarily be
    converted to a Number object, and a new property will be added to that
    object. However, it is only this temporary object that will possess the
    property, and it almost immediately ceases to exist.

    > then new objects are created but with 'standard' prototype (which is
    > Object... without myFunc3).


    Yes. If the prototype property does not reference an object, it is
    ignored and the 'original' Object prototype object will be used instead.

    [snip]

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
     
    Michael Winter, Nov 20, 2005
    #5
    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. Guest
    Replies:
    8
    Views:
    382
    Steven Cheng[MSFT]
    Dec 29, 2006
  2. Replies:
    2
    Views:
    473
    Bruno Desthuilliers
    May 26, 2008
  3. Zam
    Replies:
    1
    Views:
    264
    Mark Schupp
    Mar 14, 2005
  4. rolo
    Replies:
    3
    Views:
    197
    Robert Klemme
    Apr 9, 2004
  5. Navu

    image related thing in website

    Navu, Jan 23, 2006, in forum: Javascript
    Replies:
    2
    Views:
    100
    Thomas 'PointedEars' Lahn
    Jan 23, 2006
Loading...

Share This Page