Array as hash tables

Discussion in 'Javascript' started by Alexis Nikichine, Aug 6, 2004.

  1. Hello,

    It is common knowledge that arrays can be used as hashtables:

    var color = [];

    color["red"] = 0xFF0000;
    color["blue"] = 0x0000FF;


    With this, I can check whether a string identifies a color, or not:

    function isColor(string)
    {
    return color[string] == undefined;
    }

    My only concern is that

    isColor("pop") == true

    and that will hold true for quite a few annoying, parasitic,
    "keywords" ("constructor", "length", etc...)

    I finally came to use the following as a naked object, to use as a
    hashtable:

    function HashTable() { this.constructor = undefined; }

    // example of use:
    var color = new HashTable;
    color["red"] = 0xFF0000


    Question for experts: won't then there be other unexpected, hardcoded,
    keywords stalking my strings in the dark, and returning obscure,
    native, js objects, where I expected plain numbers ?

    Any help appreciated,


    Alexis
     
    Alexis Nikichine, Aug 6, 2004
    #1
    1. Advertising

  2. Alexis Nikichine wrote:

    > It is common knowledge that arrays can be used as hashtables:
    >
    > var color = [];
    >
    > color["red"] = 0xFF0000;
    > color["blue"] = 0x0000FF;
    >
    >
    > With this, I can check whether a string identifies a color, or not:
    >
    > function isColor(string)
    > {
    > return color[string] == undefined;
    > }
    >
    > My only concern is that
    >
    > isColor("pop") == true
    >
    > and that will hold true for quite a few annoying, parasitic,
    > "keywords" ("constructor", "length", etc...)
    >
    > I finally came to use the following as a naked object, to use as a
    > hashtable:
    >
    > function HashTable() { this.constructor = undefined; }
    >
    > // example of use:
    > var color = new HashTable;
    > color["red"] = 0xFF0000
    >
    >
    > Question for experts: won't then there be other unexpected, hardcoded,
    > keywords stalking my strings in the dark, and returning obscure,
    > native, js objects, where I expected plain numbers ?
    >
    > Any help appreciated,


    If the indexes are not integers, then use an Object, not an Array.

    var color = {};

    If the subscript is an identifier (and not a reserved word), you can use
    the stylish dot notation.

    color.red = 0xFF0000;
    color.blue = 0x0000FF;

    In HTML applications, it may be better to keep color values as strings.
    That way you won't get a false negative on black.

    color.red = "#FF0000";
    color.blue = "#0000FF";
    color.black = "#000000";

    If you use a little type discipline, then it is eay to distinguish your
    values from Object methods.

    function isColor(string) {
    return typeof color[string] == "string";
    }

    The hashtable constructor above is silly. If it doesn't have methods,
    then it is better to use a plain Object. Even better, you can use the
    object literal notation.

    color = {red: "#FF0000", blue: "#0000FF", black: "#000000"};

    http://www.JSON.org
     
    Douglas Crockford, Aug 6, 2004
    #2
    1. Advertising

  3. Douglas Crockford wrote:

    > If the indexes are not integers, then use an Object, not an Array.
    >
    > var color = {};
    >
    > If the subscript is an identifier (and not a reserved word), you can

    use
    > the stylish dot notation.
    >
    > color.red = 0xFF0000;
    > color.blue = 0x0000FF;
    >
    > In HTML applications, it may be better to keep color

    [snip>

    The color example was just a gratuitous one. I was worrying about
    arbitrary strings typed in by users. One day, I had reports of "pop art"
    request failing. "pop" yielded a function (instead of an expected
    integer).

    > If you use a little type discipline, then it is eay to distinguish

    your
    > values from Object methods.
    >
    > function isColor(string) {
    > return typeof color[string] == "string";
    > }


    When I first met the, I used type discipline, and made sure that the
    returned value was an integer.

    > The hashtable constructor above is silly. If it doesn't have methods,
    > then it is better to use a plain Object. Even better, you can use the
    > object literal notation.


    Unfortunately, I can't rely on type discipline, now, since (in another
    urelated case) I need an hash (and don't call me a perl boob :)
    returning hash, integers.

    With a plain Object, I will get an unexpected result on "constructor".

    Which is why I am asking: is my HashTable a really really empty
    Object/Function, once the "constructor" member has been blanked ?

    Alexis

    --
    some domain is free (and btw, everything I know, I learned from your
    site; thank you :)

    *** Sent via Developersdex http://www.developersdex.com ***
    Don't just participate in USENET...get rewarded for it!
     
    Alexis Nikichine, Aug 6, 2004
    #3
  4. >>If the indexes are not integers, then use an Object, not an Array.
    >>
    >>var color = {};
    >>
    >>If the subscript is an identifier (and not a reserved word), you can

    >
    > use
    >
    >>the stylish dot notation.
    >>
    >>color.red = 0xFF0000;
    >>color.blue = 0x0000FF;
    >>
    >>In HTML applications, it may be better to keep color

    >
    > [snip>
    >
    > The color example was just a gratuitous one. I was worrying about
    > arbitrary strings typed in by users. One day, I had reports of "pop art"
    > request failing. "pop" yielded a function (instead of an expected
    > integer).
    >
    >
    >>If you use a little type discipline, then it is eay to distinguish

    >
    > your
    >
    >>values from Object methods.
    >>
    >>function isColor(string) {
    >>return typeof color[string] == "string";
    >>}

    >
    >
    > When I first met the, I used type discipline, and made sure that the
    > returned value was an integer.
    >
    >
    >>The hashtable constructor above is silly. If it doesn't have methods,
    >>then it is better to use a plain Object. Even better, you can use the
    >>object literal notation.

    >
    >
    > Unfortunately, I can't rely on type discipline, now, since (in another
    > urelated case) I need an hash (and don't call me a perl boob :)
    > returning hash, integers.
    >
    > With a plain Object, I will get an unexpected result on "constructor".
    >
    > Which is why I am asking: is my HashTable a really really empty
    > Object/Function, once the "constructor" member has been blanked ?


    Yes and no. A new object is empty, but it inherits values from its
    prototype chain. Clobbering the constructor does not change that.

    If the values in your object (or for the boobs, hash) are anything but
    functions, you can use

    (typeof color[string] != 'function')

    to discriminate your values from the Object methods.

    By the way, I think this was a design error in JavaScript. The
    appearance of those methods complicates the use of objects as collections.

    http://www.crockford.com/javascript/survey.html
     
    Douglas Crockford, Aug 6, 2004
    #4
  5. > > With a plain Object, I will get an unexpected result on
    > > "constructor".
    > >
    > > Which is why I am asking: is my HashTable a really really empty
    > > Object/Function, once the "constructor" member has been blanked ?

    >
    > Yes and no. A new object is empty, but it inherits values from its
    > prototype chain. Clobbering the constructor does not change that.


    Oups; you've left me far behind on this one. What should I expect to be
    inherited by this simple as bread'n butter object :

    function plainStuff(){}

    ... code ...

    a = new plainStuff

    ?

    Should I be concerned that in the ... code ... part, someone may have
    augmented the plainStuff prototype ?

    > If the values in your object (or for the boobs, hash) are anything
    > but functions, you can use
    >
    > (typeof color[string] != 'function')
    >
    > to discriminate your values from the Object methods.
    >
    > By the way, I think this was a design error in JavaScript. The
    > appearance of those methods complicates the use of objects as
    > collections.


    I wonder too. Was not the dontEnum attribute a last minute and
    incomplete workaround for this ?

    May I suggest my definitive and foolprooh hash. Call it Collection, for
    VB boobs:

    function Collection()
    {
    this.constructor = undefined;
    Collection.prototype = undefined;
    }

    Is it enough clobbering ?


    Alexis

    --
    some domain is free

    *** Sent via Developersdex http://www.developersdex.com ***
    Don't just participate in USENET...get rewarded for it!
     
    Alexis Nikichine, Aug 6, 2004
    #5
  6. (Alexis Nikichine) writes:

    > It is common knowledge that arrays can be used as hashtables:
    >
    > var color = [];
    >
    > color["red"] = 0xFF0000;
    > color["blue"] = 0x0000FF;


    It is less common knowledge that arrays are overkill for this, and
    that plain objects are better suited:

    var color = {}; // or: new Object();
    color["red"] = 0xff0000;
    color["blue"] = 0x0000ff;

    > With this, I can check whether a string identifies a color, or not:
    >
    > function isColor(string)
    > {
    > return color[string] == undefined;


    That would be better as:
    return color[string] === undefined;
    or, for browsers where "undefined" is not defined (the irony!) you
    can define it as:
    window.undefined = window.undefined;
    or you could use
    return (typeof color[string]) == "undefined";

    > My only concern is that
    >
    > isColor("pop") == true
    >
    > and that will hold true for quite a few annoying, parasitic,
    > "keywords" ("constructor", "length", etc...)


    Fewer if using objects instead of arrays, but still some (e.g. toString).

    > I finally came to use the following as a naked object, to use as a
    > hashtable:
    >
    > function HashTable() { this.constructor = undefined; }
    >
    > // example of use:
    > var color = new HashTable;
    > color["red"] = 0xFF0000


    Yes. That's just a plain object as well, with no properties except
    those inherited from Object.prototype (and even with "constructor"
    removed).

    > Question for experts: won't then there be other unexpected, hardcoded,
    > keywords stalking my strings in the dark, and returning obscure,
    > native, js objects, where I expected plain numbers ?


    According to ECMA 262 v3 section 5.2.4:
    toString, toLocaleString, valueOf, hasOwnProperty, isPrototypeOf,
    propertyIsEnumerable.
    (you overwrote "constructor", otherwise it would be there too).

    > Any help appreciated,


    All these properties are functions. All your stored values are
    numbers. Try:

    function isColor(string){
    return (typeof color[string])=="number";
    }

    In recent versions of browsers, you can also use:

    function isColor(string) {
    return color.hasOwnProperty(string);
    }

    That only counts the properties of the object itself, not its
    prototypes. In any case, you can just use "new Object()" instead
    of "new HashTable()".

    /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, Aug 6, 2004
    #6
  7. Douglas Crockford <> writes:

    > functions, you can use
    >
    > (typeof color[string] != 'function')
    >
    > to discriminate your values from the Object methods.
    >
    > By the way, I think this was a design error in JavaScript. The
    > appearance of those methods complicates the use of objects as
    > collections.


    It has been somehow mitigated by later additions to, of all things,
    Object.prototype :).

    All the properties of Object.prototype are non-enumerable, so you
    can test against non-original properties as:

    propName in objectRef && !objectRef.propertyIsEnumerable(propName)

    (or, if only adding to one object an not inheriting from it:
    objectRef.hasOwnProperty(propName)
    )
    /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, Aug 6, 2004
    #7
  8. Alexis Nikichine wrote:
    <snip>
    > The color example was just a gratuitous one. I was worrying
    > about arbitrary strings typed in by users. One day, I had
    > reports of "pop art" request failing. "pop" yielded a
    > function (instead of an expected integer).

    <snip>

    If you want to store key/value pairs without any restrictions to the
    names perhaps you need to implement an object for that storage. Maybe in
    a Java style with - get - and - put - (and maybe - remove -) methods.
    With an internal naming system that allows referencing by key but does
    not directly use that key as a property name. You could genuinely hash
    the keys to a number and then represent that number as a string property
    name, but that would be quite an overhead to add to each reference. A
    satisfactory indirect use of the key might be to append a space
    character to the front of it, producing a property name that will never
    conflict with any prototype inherited property of an object. A simple
    implementation might go:-

    function SafeHash(){
    var safeName = [' '];
    var values = {};
    this.get = function(key){
    safeName[1] = key;
    return values[safeName.join('')]
    };
    this.put = function(key, value){
    safeName[1] = key;
    values[safeName.join('')] = value;
    };
    this.remove = function(key){
    safeName[1] = key;
    delete values[safeName.join('')];
    };
    }

    A more complex version, implementing most of the pertinent methods form
    the Java Hashtable, and returning Enumerator (and Iterator) Interfaces
    for keys and values, might go:-

    var Hashtable = (function(){
    var keyAdj = [' '];
    /* This private static Object constructor is used to implement
    a Java style Enumerator (and Iterator) Interface:-
    */
    function Enumeration(arrNm, activeEnum, keysToIndex){
    var lastIndex = null;
    var enumIndex = 0;
    while(typeof activeEnum[enumIndex] == 'number'){enumIndex++;}
    activeEnum[enumIndex] = 0;
    this.hasNext = this.hasMoreElements = function(){
    if(activeEnum[enumIndex] < keysToIndex.tableLength){
    return true;
    }else{
    if(typeof activeEnum[enumIndex] == 'number'){
    activeEnum[enumIndex] = null;
    }
    return false;
    }
    };
    this.next = this.nextElement = function(){
    if(this.hasNext()){
    lastIndex = activeEnum[enumIndex];
    return keysToIndex[arrNm][activeEnum[enumIndex]++];
    }else{
    return null;
    }
    };
    this.remove = function(){
    if(typeof lastIndex == 'number'){
    removeItem(keysToIndex._indexToKeys[lastIndex],
    keysToIndex, activeEnum);
    lastIndex = null;
    }
    };
    };
    function removeItem(key, keysToIndex, activeEnum){
    keyAdj[1] = key;
    key = keyAdj.join('');
    var remIndex = keysToIndex[key];
    if(typeof remIndex == 'number'){
    delete keysToIndex[key];
    keysToIndex.tableLength--;
    for(var c = remIndex;c < keysToIndex.tableLength;c++){
    keysToIndex._indexToValue[c] =
    keysToIndex._indexToValue[c+1];
    keyAdj[1] = (keysToIndex._indexToKeys[c] =
    keysToIndex._indexToKeys[c+1]);
    keysToIndex[keyAdj.join('')] = c;
    }
    keysToIndex._indexToValue.length = keysToIndex.tableLength;
    for(var c = activeEnum.length;c--;){
    if((activeEnum[c])&&(remIndex < activeEnum[c])){
    activeEnum[c]--;
    }
    }
    }
    }
    /* Hashtable object constructor fuction:-
    */
    function HTable(){
    var keysToIndex ={_indexToValue:[],_indexToKeys:[],tableLength:0};
    var activeEnum = [];
    this.get = function(key){
    keyAdj[1] = key;
    key = keyAdj.join('');
    if(typeof keysToIndex[key] == 'number'){
    return keysToIndex._indexToValue[keysToIndex[key]];
    }else{
    return null;
    }
    };
    this.put = function(key, value){
    keyAdj[1] = key;
    var sKey = keyAdj.join('');
    if(typeof keysToIndex[sKey] == 'number'){
    keysToIndex._indexToValue[keysToIndex[sKey]] = value;
    }else{
    keysToIndex[sKey] = keysToIndex.tableLength;
    keysToIndex._indexToValue[keysToIndex.tableLength] = value;
    keysToIndex._indexToKeys[keysToIndex.tableLength++] = key;
    }
    };
    this.remove = function(key){
    removeItem(key, keysToIndex, activeEnum);
    };
    this.containsKey = function(key){
    keyAdj[1] = key;
    return (typeof keysToIndex[keyAdj.join('')] == 'number');
    };
    this.size = function(){return keysToIndex.tableLength;};
    this.elements = function(){
    return new Enumeration('_indexToValue',activeEnum, keysToIndex);
    };
    this.keys = function(){
    return new Enumeration('_indexToKeys', activeEnum, keysToIndex);
    };
    }
    HTable.prototype.clear = function(){
    var e = this.keys();
    while(e.hasNext()){
    this.remove(e.next());
    }
    };
    HTable.prototype.toString = function(){
    var k,e = this.keys();
    var st = '';
    while(e.hasNext()){
    k = e.next();
    st += k+' = '+this.get(k)+'\n';
    }
    return st;
    };
    HTable.prototype.containsValue =
    (HTable.prototype.contains = function(testVal){
    var v,e = this.elements();
    while(e.hasNext()){
    v = e.next();
    if(v === testVal){
    //if((v == testVal)&&(typeof v == typeof testVal)){
    return true;
    }
    }
    return false;
    });
    HTable.prototype.isEmpty = function(){
    return (this.size() == 0);
    };
    HTable.prototype.putAll = function(hTable){
    if((typeof hTable == 'object')&&
    (hTable.constructor == HTable)){
    var n,e = hTable.keys();
    while(e.hasNext()){
    n = e.next();
    this.put(n, hTable.get(n));
    }
    }
    return this;
    };
    HTable.prototype.clone = function(){
    return new HTable().putAll(this);
    };
    HTable.prototype.equals = function(o){
    return (o == this);
    };
    return HTable; //return the Hashtable object constructor.
    })();

    The optimum functionality for your application will probably lye
    somewhere in-between the two.

    Richard.
     
    Richard Cornford, Aug 6, 2004
    #8
  9. >>If the values in your object (or for the boobs, hash) are anything
    >>but functions, you can use
    >>
    >>(typeof color[string] != 'function')
    >>
    >>to discriminate your values from the Object methods.
    >>
    >>By the way, I think this was a design error in JavaScript. The
    >>appearance of those methods complicates the use of objects as
    >>collections.

    >
    >
    > I wonder too. Was not the dontEnum attribute a last minute and
    > incomplete workaround for this ?


    The problem with dontEnum is that it didn't make it into the language;
    it is only in the implementation. It only controls the results of
    for..in, so it does not help you in this case, anyway.

    > May I suggest my definitive and foolproof hash. Call it Collection, for
    > VB boobs:
    >
    > function Collection()
    > {
    > this.constructor = undefined;
    > Collection.prototype = undefined;
    > }
    >
    > Is it enough clobbering ?


    No. The [[prototype]] property is the key one, and it is still there.
    Clobbering is not effective. You will still see the Object methods (but
    there are fewer of them than there are Array methods).

    Something that might work is

    function Collection() {}
    Collection.prototype = {constructor: null, toString: null,
    prototype: null};

    http://www.crockford.com/#javascript
     
    Douglas Crockford, Aug 6, 2004
    #9
  10. Douglas Crockford <> writes:

    > Something that might work is
    >
    > function Collection() {}
    > Collection.prototype = {constructor: null, toString: null,
    > prototype: null};


    A new object created from "new Collection()" will not have a "prototype"
    property, so "prototype: null" is not needed.

    The full monty would be:
    ---
    function Collection(){}
    Collection.prototype = {
    constructor: undefined,
    toString : undefined,
    toLocaleString : undefined,
    valueOf : undefined,
    hasOwnProperty: undefined,
    isPropertyOf: undefined,
    propertyIsEnumerable: undefined
    };
    ---
    However, there is no need for the Collection *constructor* then. When
    you just need an empty collection, you can create a new one directly:

    ---
    function createCollection() {
    return {
    constructor: undefined,
    toString : undefined,
    toLocaleString : undefined,
    valueOf : undefined,
    hasOwnProperty: undefined,
    isPropertyOf: undefined,
    propertyIsEnumerable: undefined
    };
    }
    ---

    (Ofcourse, some implementations might have other, non-standard,
    properties on Object.prototype :)

    /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, Aug 6, 2004
    #10
  11. In article <>, Alexis
    Nikichine <> writes

    <snip>
    >I finally came to use the following as a naked object, to use as a
    >hashtable:

    <snip>

    Why do you call it a hashtable? It could just as easily be a balanced
    tree or even a simple list. You wouldn't be able to tell the difference.

    If you want to be posh, and accurate too, call it an associative array.
    If you want to be less posh you could call it a map.

    John
    --
    John Harris
     
    John G Harris, Aug 6, 2004
    #11
  12. Lasse Reichstein Nielsen wrote:
    <snip>
    > (Ofcourse, some implementations might have other,
    > non-standard, properties on Object.prototype :)


    Such as Mozilla:-

    __defineGetter__
    __defineSetter__
    __parent__
    __proto__
    eval
    toSource
    unwatch
    watch

    Richard.
     
    Richard Cornford, Aug 6, 2004
    #12
  13. >>I finally came to use the following as a naked object, to use as a
    >>hashtable


    > Why do you call it a hashtable? It could just as easily be a balanced
    > tree or even a simple list. You wouldn't be able to tell the difference.
    >
    > If you want to be posh, and accurate too, call it an associative array.
    > If you want to be less posh you could call it a map.


    And if you want to be understood in a JavaScript forum, you would call
    it an object.

    http://www.crockford.com/javascript/javascript.html
     
    Douglas Crockford, Aug 6, 2004
    #13
  14. Richard Cornford wrote:

    >>(Ofcourse, some implementations might have other,
    >>non-standard, properties on Object.prototype :)

    >
    >
    > Such as Mozilla:-
    >
    > __defineGetter__
    > __defineSetter__
    > __parent__
    > __proto__
    > eval
    > toSource
    > unwatch
    > watch


    JFTR <URL:http://lxr.mozilla.org/seamonkey/source/js/src/jsobj.c#1535>
    provides the last two methods : __lookupGetter__ and __lookupSetter__.


    Regards,
    Yep.
     
    Yann-Erwan Perio, Aug 6, 2004
    #14
  15. Alexis Nikichine

    rh Guest

    "Richard Cornford" wrote:

    > Alexis Nikichine wrote:
    > <snip>
    > > The color example was just a gratuitous one. I was worrying
    > > about arbitrary strings typed in by users. One day, I had
    > > reports of "pop art" request failing. "pop" yielded a
    > > function (instead of an expected integer).

    > <snip>
    >
    > If you want to store key/value pairs without any restrictions to the
    > names perhaps you need to implement an object for that storage.


    That's unfortunate. Truthfully, this is a name-scope conflict with
    genesis imbedded as a deficiency of the language (a statement made
    notwithstanding the fact that JavaScript remains, by far, my favourite
    progamming language). It should be possible to obtain a basic object
    that is entirely clear of such name conflicts.

    Given that, and ever seemingly the contrarian, I don't believe that
    Alexis is that far off track in attempting to remedy the deficiency
    through removal of pre-definded values in the object. The latter day
    "propertyIsEnumerable" mentioned by Lasse, it seems, is a rather late,
    lame fix to the language.

    ../rh
     
    rh, Aug 7, 2004
    #15
  16. rh wrote:
    > "Richard Cornford" wrote:

    <snip>
    >> If you want to store key/value pairs without any restrictions to the
    >> names perhaps you need to implement an object for that storage.

    >
    > That's unfortunate. Truthfully, this is a name-scope conflict with
    > genesis imbedded as a deficiency of the language (a statement made
    > notwithstanding the fact that JavaScript remains, by far, my favourite
    > progamming language). It should be possible to obtain a basic object
    > that is entirely clear of such name conflicts.
    >
    > Given that, and ever seemingly the contrarian, I don't believe that
    > Alexis is that far off track in attempting to remedy the deficiency
    > through removal of pre-definded values in the object. ...


    We have seen that Mozilla is admitting to adding some non-standard
    properties to its JS objects. I am fairly sure that I have also seen
    some similar non-standard properties on Konqueror objects, as apparently
    exposed implementation details (I don't have time to re-check right
    now). That makes relying on blanking a list of expected properties
    unsatisfactory, as it would be difficult to guarantee that the list was
    comprehensive across JS implementations.

    Adding a space to the front of the property names is not guaranteed to
    be absolutely safe either, but the chances of coincidence are lower and
    programmers are unlikely to make JS implementations that used space
    prefixed property names (not least because most other languages would
    not allow it).

    Richard.
     
    Richard Cornford, Aug 7, 2004
    #16
  17. In article <d3526$4113e8c6$43656322$>,
    Douglas Crockford <> writes
    >>>I finally came to use the following as a naked object, to use as a
    >>>hashtable

    >
    >> Why do you call it a hashtable? It could just as easily be a balanced
    >> tree or even a simple list. You wouldn't be able to tell the difference.
    >> If you want to be posh, and accurate too, call it an associative
    >>array.
    >> If you want to be less posh you could call it a map.

    >
    >And if you want to be understood in a JavaScript forum, you would call
    >it an object.


    But I thought the whole point of this thread was that a javascript
    object isn't good enough to be an any name in, correct value out kind of
    thing, or map as we might call it.

    Also I'm surprised no-one has suggested prefixing each name with
    something unlikely, such as "TQ7_".

    John
    --
    John Harris
     
    John G Harris, Aug 7, 2004
    #17
  18. Alexis Nikichine

    rh Guest

    "Richard Cornford" wrote:
    > rh wrote:
    > > "Richard Cornford" wrote:

    <..>
    > We have seen that Mozilla is admitting to adding some non-standard
    > properties to its JS objects. I am fairly sure that I have also seen
    > some similar non-standard properties on Konqueror objects, as apparently
    > exposed implementation details (I don't have time to re-check right
    > now).


    I wasn't aware of that, but it does go right to the heart of the
    design problem that exists. Under the current model of objects having
    a single namespace, it isn't possible to extend native properties of
    the JS object without potentially breaking existing programs.

    Of course, given prototype inheritance, the single namespace is far
    more a blessing than a curse.

    > That makes relying on blanking a list of expected properties
    > unsatisfactory, as it would be difficult to guarantee that the list was
    > comprehensive across JS implementations.
    >


    Yes, so now I want to be provided with a native method that will
    return a list of property names that manifest through the prototype
    chain :).

    Or perhaps, to obtain a completely unencumbered object, I just want to
    be able to turn off the prototype chain processing?

    ../rh
     
    rh, Aug 7, 2004
    #18
  19. John G Harris <> writes:

    > But I thought the whole point of this thread was that a javascript
    > object isn't good enough to be an any name in, correct value out kind of
    > thing, or map as we might call it.


    It works fine for that. The problem is that it doesn't start out empty,
    but wnything you put in, you get out again fine.

    > Also I'm surprised no-one has suggested prefixing each name with
    > something unlikely, such as "TQ7_".


    Richard did. He suggested a single space IIRC.


    Ok, an associative array implementation that isn't fooled by standard
    or non-standard values:
    ---
    function Map() {
    this.map = {};
    }
    Map.Value = function Value(v) {
    this.value = v;
    }
    Map.prototype.containsKey = function containsKey(k) {
    return (this.map[k]) instanceof Map.Value;
    }
    Map.prototype.put = function put(k,v) {
    this.map[k] = new Map.Value(v);
    };
    Map.prototype.get = function get(k) {
    var v = this.map[k];
    if (v instanceof Map.Value) {
    return v.value;
    }
    };
    Map.prototype.remove = function remove(k) {
    delete this.map[k]
    };
    ---

    /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, Aug 7, 2004
    #19
  20. rh wrote:
    > Richard Cornford wrote:

    <snip>
    > Or perhaps, to obtain a completely unencumbered object, I just
    > want to be able to turn off the prototype chain processing?


    The implication in the ECMA specified [[construct]] method is that
    either an object must be assigned to the internal [[prototype]] property
    of a newly created object or the original Object.prototype will be used
    (not even the current Object.prototype). I don't see any way of
    acquiring a reference to an object with less than one object on its
    prototype chain.

    Richard.
     
    Richard Cornford, Aug 8, 2004
    #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. rp
    Replies:
    1
    Views:
    557
    red floyd
    Nov 10, 2011
  2. Anthony Martinez
    Replies:
    4
    Views:
    286
    Robert Klemme
    Jun 11, 2007
  3. Michal Suchanek
    Replies:
    6
    Views:
    242
    Nobuyoshi Nakada
    Jun 13, 2007
  4. Srijayanth Sridhar
    Replies:
    19
    Views:
    641
    David A. Black
    Jul 2, 2008
  5. Ted Flethuseo

    building an array of hash tables.

    Ted Flethuseo, Jul 26, 2010, in forum: Ruby
    Replies:
    1
    Views:
    116
    Joel VanderWerf
    Jul 26, 2010
Loading...

Share This Page