Language Confusions

Discussion in 'Javascript' started by Gene Wirchenko, Nov 24, 2011.

  1. Dear JavaScripters:

    I have been carefully studying JavaScript and have learned a lot
    more than I ever knew about it. I have some questions about niggling
    points:

    1) What is the difference between:
    s="Hello";
    s=new String("Hello");
    s=String("Hello");
    The text I am studying says that the first two are the same. Fine.
    The third behaves the same way AFAICS. Could someone please
    illustrate the difference?

    2) I am unclear on exactly all what .prototype does. For adding
    methods to an object type, fine. In the text that I am studying,
    there is an example of a table object. The author then shows how to
    add a method to an object type (without modifying the base code), and
    how it is done has me puzzled:
    function table_colorWrite(doc)
    body omitted
    followed by
    table.prototype.colorWrite=table_colorWrite
    I am not clear on what .prototype does in this line. I think I must
    be missing something about the JavaScript object model.

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Nov 24, 2011
    #1
    1. Advertisements

  2. Gene Wirchenko

    J.R. Guest

    If you paste the following code snippet in a JavaScript console such as
    Firebug's (in Firefox), you will notice the difference:

    var s1 = "Hello",
    s2 = new String("Hello"),
    s3 = String("Hello");

    console.log(typeof s1); // "string"
    console.log(typeof s2); // "object"
    console.log(typeof s3); // "string"

    So "the first two are the same" is wrong... Check the ECMAScript
    Language Specification to learn the why's.
    An explanation about prototype in JavaScript would require a lot of
    typing here... So I'd suggest a further reading at
    <http://javascript.crockford.com/prototypal.html>
     
    J.R., Nov 24, 2011
    #2
    1. Advertisements

  3. My reluctance to recommend javascript books is, at least in part,
    motivated by the very low level of technical veracity found in most
    texts on the subject. The first two are absolutely different. The
    first assigns a string primitive value to - s -, and the second
    creates a String object and assigns that to - s -. Testing the values
    with the - typeof - operator will directly show the difference, as
    would code like:-
    s = 'Hello';
    s.newProp = 'something';
    alert(s.newProp); // alerts 'undefined'

    - while:-
    s = 'Hello';
    s.newProp = 'something';
    alert(s.newProp); // alerts 'something'

    - as all object may have properties assigned to them and retain the
    values of those properties. While doing the same with a string
    primitive will result in an internal type-conversion of the primitive
    to a string object (in order to resolve the dot notation property
    accessor) and the assignment happens on that object, but later reading
    the property with another dot notation property accessor causes
    another internal type-conversion and the creation of a new String
    object, and so the named property of that new object is undefined.
    (This latter may sound inefficient, but ECMAScript is only required to
    behave as if it does this and the implementations tend to be more
    efficient in the way that they achieve the specified outocmes.)
    The third has the same outcome as the first, in that a string
    primitive ends up assigned to - s -. Calling the - String -
    constructor as a function (so without the - new - operator) always
    results in a string primitive. If its argument is not a string
    primitive then it applies the language's type-conversion rules to get
    a string primitive, but when the argument is a string primitive, as in
    this case, then it just returns that string. The call to the - String
    - function is redundant whenever the argument is already known to be a
    string primitive.
    The balance of probability is that the third could be shown to be
    slower to execute than the first, but are otherwise identical in their
    outcome. The second can be shown to result in a different type of
    value from the other two using the - typeof - operator.
    All functions are objects, and when they are created they are assigned
    a number of (internal and exposed (visible or public) properties. One
    of the exposed properties that they always get is named - prototype -,
    and that property is initially assigned a new object (the equivalent
    of the result of a call to new Object, except that the new object is
    given a - constructor - property to which the 'owning' function object
    is assigned).
    Adding properties, those properties may have functions as their values
    (which would then be generally considered as methods) but you can also
    inherit any other values (and inheriting default primitive values for
    properties that may or may not later be assigned is normal/usual).
    When an object is created by applying the - new - operator to a
    function a new object is created, and the internal [[Prototype]]
    property is assigned whatever object is the value of the function's -
    prototype - property at the time of the - new - operation. The
    internal [[Prototype]] property (exposed as - __proto__ - in some
    language implementations) is used in resolving property names against
    an object. So if you do:-

    function Something(){
    //function body
    }
    Something.prototype.test = 'xx';

    var obj = new Something();

    obj.addedProp = 'yy';

    - and then do:-

    var s = obj.addedProp;

    -then you are reading the property with the name - addedProp -
    directly from the - obj - object. However if you do:-

    s = obj.test;

    - the - obj -object does not have a - test - property, so the system
    looks at the internal [[Prototype]] property of - obj -, and if it is
    an object it attempts to read the - test - property from that object.
    Because - Something.prototype - has been assigned to the - obj -
    object's internal [[Prototype]] property, and the -
    Something.prototype - has a - test - property,- obj.test - is resolved
    as the value of that property.

    Additionally, if you do:-

    s = obj.toString;

    - then neither - obj - nor - Something.prototype - have a - toString -
    property themselves, but when the object that was assigned to -
    Something.prototype - was created its internal [[Prototype]] property
    as set to - Object.prototype - (because its creation was the
    equivalent of - new Object(); -). The object referred to by -
    Object.prototype - has a - toString - property so - obj.toString - is
    resolved as the value of that property. The - Object.prototype -
    object has its internal [[Prototype]] property set to null, and so the
    structure that is referred to as an object's "prototype chain" ends at
    that point.

    The named properties of objects are resolved against the object's
    prototype chain, which in the case of the example object looks like:-

    obj ->
    (obj.[[prototype]] === Something.prototype) ->
    ( Something.prototype.[[prototype]] === Object.prototype) ->
    ( Object.prototype.[[prototype]] === null)

    This "prototype chain" structure is used for javascript's natural/
    native inheritance for objects. Multiple object instances can/will
    share the same single object as their [[prototype]], inheriting all of
    the properties of that object.

    Even after the assignment of objects to the internal [[Prototype]]
    property those object can be modified by, for example, adding new
    properties. Thus following the execution of the above code:-

    alert(obj.somethingNew);

    -alerts 'undefined' (no object on the prototype chain has a -
    somethingNew - property). But then if you execute:-

    Something.prototype.somethingNew = 5;
    alert(obj.somethingNew);

    - now alerts '5', even though nothing has directly been done to - obj
    - to give it that new property.

    Also, it is possible to assign any value to the - prototype - property
    of a function object, and it is only the value assigned at the time of
    the evaluation of a - new - operation that influences the internal
    [[Prototype]] property of the newly created object.

    Richard.
     
    Richard Cornford, Nov 24, 2011
    #3
  4. I may be more gracious than you about it, but not by much:

    I am finding that JavaScript documentation tends to come in two
    varieties: 1) trivial that does not give enough information and 2)
    detailed but wrong. Note how my point 1 allows for the information to
    be correct.

    [snipped explanation]

    A very nice one, thank you. I was able to verify it easily. That
    really helped.

    [snip]

    I have saved this, but I am going to have to chew on it later.
    Thank you again.

    Sicnerely,

    Gene Wirchenko
     
    Gene Wirchenko, Nov 24, 2011
    #4
    1. Advertisements

Ask a Question

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

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