Loading ...
Sorry, an error occurred while loading the content.

Re: [jslint] I must use 'new String'

Expand Messages
  • Stefan Weiss
    ... That s not JSON, it s just an object literal. As to the previous example: var str = somestring ; str.id = 123; str.id; // undefined The reason why this
    Message 1 of 15 , Feb 17, 2010
    • 0 Attachment
      On 17/02/10 14:11, Klemen Slavič wrote:
      > Why not use JSON to carry values in such a case?
      >
      > var a = {
      > value: "somestring",
      > id: 123
      > };

      That's not JSON, it's just an object literal.

      As to the previous example:

      var str = "somestring";
      str.id = 123;
      str.id; // undefined

      The reason why this can't work is that in lines 2 and 3, str is
      converted from a string primitive to a new String object. This happens
      every time you try to use a string (or number, or boolean) primitive
      type like an object --> str gets auto-converted into an object twice,
      but only internally, for the purpose of property lookup. The two created
      String objects are then thrown away, and the "id" property is lost.

      For the OP: I agree with Klemen and the walfisch - wrapping your string
      and any additional properties in a custom object is the way to go.
      Augmenting one instance of a String object sounds like flaky design; I
      sure wouldn't expect it if I read your code.


      --
      stefan
    • Klemen Slavič
      Ah, yes, I misspoke. *Note to self: proof email before replying.* ... [Non-text portions of this message have been removed]
      Message 2 of 15 , Feb 17, 2010
      • 0 Attachment
        Ah, yes, I misspoke.

        *Note to self: proof email before replying.*

        On 18 February 2010 06:30, Stefan Weiss <weiss@...> wrote:

        >
        >
        > On 17/02/10 14:11, Klemen Slavič wrote:
        > > Why not use JSON to carry values in such a case?
        > >
        > > var a = {
        > > value: "somestring",
        > > id: 123
        > > };
        >
        > That's not JSON, it's just an object literal.
        >
        > As to the previous example:
        >
        >
        > var str = "somestring";
        > str.id = 123;
        > str.id; // undefined
        >
        > The reason why this can't work is that in lines 2 and 3, str is
        > converted from a string primitive to a new String object. This happens
        > every time you try to use a string (or number, or boolean) primitive
        > type like an object --> str gets auto-converted into an object twice,
        > but only internally, for the purpose of property lookup. The two created
        > String objects are then thrown away, and the "id" property is lost.
        >
        > For the OP: I agree with Klemen and the walfisch - wrapping your string
        > and any additional properties in a custom object is the way to go.
        > Augmenting one instance of a String object sounds like flaky design; I
        > sure wouldn't expect it if I read your code.
        >
        > --
        > stefan
        >
        >
        >


        [Non-text portions of this message have been removed]
      • Morgaut Alexandre Louis Marc
        For the exposed use case I wouldn t recommend this kind of weird custom objects wich wouldn t have any string methods and wouldn t be seen as string by typeof
        Message 3 of 15 , Feb 17, 2010
        • 0 Attachment
          For the exposed use case I wouldn't recommend this kind of weird
          custom objects wich wouldn't have any string methods and wouldn't be
          seen as string by typeof

          My suggestion would be to use an external object for additional
          properties like this :

          var strProps = {};

          var str = "something";

          strProps[str] = {
          id: 123
          };

          You can either use a namespaced strProps (like myApp.strProps) or a
          local one for more privacy depending of your requirements

          Alexandre



          Le 18 févr. 10 à 06:30, Stefan Weiss a écrit :

          > On 17/02/10 14:11, Klemen Slavič wrote:
          > > Why not use JSON to carry values in such a case?
          > >
          > > var a = {
          > > value: "somestring",
          > > id: 123
          > > };
          >
          > That's not JSON, it's just an object literal.
          >
          > As to the previous example:
          >
          > var str = "somestring";
          > str.id = 123;
          > str.id; // undefined
          >
          > The reason why this can't work is that in lines 2 and 3, str is
          > converted from a string primitive to a new String object. This happens
          > every time you try to use a string (or number, or boolean) primitive
          > type like an object --> str gets auto-converted into an object twice,
          > but only internally, for the purpose of property lookup. The two
          > created
          > String objects are then thrown away, and the "id" property is lost.
          >
          > For the OP: I agree with Klemen and the walfisch - wrapping your
          > string
          > and any additional properties in a custom object is the way to go.
          > Augmenting one instance of a String object sounds like flaky design; I
          > sure wouldn't expect it if I read your code.
          >
          > --
          > stefan
          >
          >



          [Non-text portions of this message have been removed]
        • Stefan Weiss
          ... The OP was planning on using a String object, which would have a type of object , so I don t think that matters much. Furthermore, the receiving code
          Message 4 of 15 , Feb 18, 2010
          • 0 Attachment
            On 18/02/10 08:37, Morgaut Alexandre Louis Marc wrote:
            > For the exposed use case I wouldn't recommend this kind of weird
            > custom objects wich wouldn't have any string methods and wouldn't be
            > seen as string by typeof

            The OP was planning on using a String object, which would have a type of
            "object", so I don't think that matters much. Furthermore, the receiving
            code wasn't expecting normal Strings anyway (it would be looking for an
            "id" property). If plain Object objects are too "weird", he could make
            it official and define a constructor:

            function SpecialString (str, id) {
            this.value = str;
            this.id = id;
            }

            var str = new SpecialString("somestring", 123);

            This way, there would be no confusion, and no more JSLint warnings.

            > My suggestion would be to use an external object for additional
            > properties like this :
            >
            > var strProps = {};
            >
            > var str = "something";
            >
            > strProps[str] = {
            > id: 123
            > };
            >
            > You can either use a namespaced strProps (like myApp.strProps) or a
            > local one for more privacy depending of your requirements

            That would work, of course, but it would separate two parts of
            information which belong together as an entity. I find that less
            appealing than having them in one object. You also coulnd't have two
            strings with the same value but different IDs.


            --
            stefan
          • Woomla
            ... I ve come up with the solution below. It runs in FF and IE and it uses data hiding. By implementing toString it behaves like a regular string. Only typeof
            Message 5 of 15 , Feb 18, 2010
            • 0 Attachment
              --- In jslint_com@yahoogroups.com, Stefan Weiss <weiss@...> wrote:
              > The OP was planning on using a String object, which would have a type of
              > "object", so I don't think that matters much. Furthermore, the receiving
              > code wasn't expecting normal Strings anyway (it would be looking for an
              > "id" property). If plain Object objects are too "weird", he could make
              > it official and define a constructor:
              >
              > function SpecialString (str, id) {
              > this.value = str;
              > this.id = id;
              > }
              >
              > var str = new SpecialString("somestring", 123);
              >
              > This way, there would be no confusion, and no more JSLint warnings.


              I've come up with the solution below. It runs in FF and IE and it uses data hiding. By implementing toString it behaves like a regular string. Only typeof returns 'object'.


              var MyString = (function ()
              {
              var thevalue, itself;
              thevalue = '';
              itself = function (value)
              {
              thevalue = value;
              };
              itself.prototype.$family = {name: 'mystring'};
              itself.prototype.toString = function ()
              {
              return thevalue;
              };
              return itself;
              }());
            • Klemen Slavič
              Regarding the type; I think it s for the best that it returns object instead of string ; that way, you know you re handling a special type instead of a
              Message 6 of 15 , Feb 18, 2010
              • 0 Attachment
                Regarding the type; I think it's for the best that it returns 'object'
                instead of 'string'; that way, you know you're handling a special type
                instead of a vanilla string, which is much more concise and understandable.



                On 18 February 2010 15:13, Woomla <woomla@...> wrote:

                >
                >
                > --- In jslint_com@yahoogroups.com <jslint_com%40yahoogroups.com>, Stefan
                > Weiss <weiss@...> wrote:
                > > The OP was planning on using a String object, which would have a type of
                > > "object", so I don't think that matters much. Furthermore, the receiving
                > > code wasn't expecting normal Strings anyway (it would be looking for an
                > > "id" property). If plain Object objects are too "weird", he could make
                > > it official and define a constructor:
                > >
                > > function SpecialString (str, id) {
                > > this.value = str;
                > > this.id = id;
                > > }
                > >
                > > var str = new SpecialString("somestring", 123);
                > >
                > > This way, there would be no confusion, and no more JSLint warnings.
                >
                > I've come up with the solution below. It runs in FF and IE and it uses data
                > hiding. By implementing toString it behaves like a regular string. Only
                > typeof returns 'object'.
                >
                > var MyString = (function ()
                > {
                > var thevalue, itself;
                > thevalue = '';
                > itself = function (value)
                > {
                > thevalue = value;
                > };
                > itself.prototype.$family = {name: 'mystring'};
                > itself.prototype.toString = function ()
                > {
                > return thevalue;
                > };
                > return itself;
                > }());
                >
                >
                >


                [Non-text portions of this message have been removed]
              • Stefan Weiss
                ... I wouldn t do that. The string value is now bound to the variable thevalue instead of to the object itself: var str1 = new MyString( foo ); var str2 = new
                Message 7 of 15 , Feb 18, 2010
                • 0 Attachment
                  On 18/02/10 15:13, Woomla wrote:
                  > I've come up with the solution below. It runs in FF and IE and it
                  > uses data hiding. By implementing toString it behaves like a regular
                  > string.
                  > Only typeof returns 'object'.
                  >
                  > var MyString = (function ()
                  > {
                  > var thevalue, itself;
                  > thevalue = '';
                  > itself = function (value)
                  > {
                  > thevalue = value;
                  > };
                  > itself.prototype.$family = {name: 'mystring'};
                  > itself.prototype.toString = function ()
                  > {
                  > return thevalue;
                  > };
                  > return itself;
                  > }());

                  I wouldn't do that. The string value is now bound to the variable
                  thevalue instead of to the object itself:

                  var str1 = new MyString("foo");
                  var str2 = new MyString("bar");
                  str1.toString(); // bar
                  str2.toString(); // bar

                  Why not use a normal constructor?

                  function MyString (str, id) {
                  this.value = str;
                  this.id = id;
                  }
                  MyString.prototype = {
                  $family: "mystring",
                  toString: function () {
                  return this.value;
                  }
                  };

                  No closures required.

                  Or, if you really _have_ keep the properties internal:

                  function makeMeAString (str, id) {
                  var secretStr = str,
                  secretId = id;
                  return {
                  $family: "mystring",
                  toString: function () { return secretStr; },
                  getId: function () { return secretId; }
                  };
                  }

                  var str1 = makeMeAString("foo", 123);
                  var str2 = makeMeAString("bar", 123);
                  str1.toString(); // "foo"
                  str2.toString(); // "bar"
                  str1.getId(); // "123"
                  str2.$family; // "mystring"

                  But I don't see the advantage in your case.


                  --
                  stefan
                • Woomla
                  ... This doesn t work. I must use this.value in function itself and toString because otherwise the value is not bound to the object and subsequent MyString
                  Message 8 of 15 , Feb 18, 2010
                  • 0 Attachment
                    --- In jslint_com@yahoogroups.com, "Woomla" <woomla@...> wrote:
                    > I've come up with the solution below. It runs in FF and IE and it uses data hiding. By implementing toString it behaves like a regular string. Only typeof returns 'object'.
                    >
                    >
                    > var MyString = (function ()
                    > {
                    > var thevalue, itself;
                    > thevalue = '';
                    > itself = function (value)
                    > {
                    > thevalue = value;
                    > };
                    > itself.prototype.$family = {name: 'mystring'};
                    > itself.prototype.toString = function ()
                    > {
                    > return thevalue;
                    > };
                    > return itself;
                    > }());


                    This doesn't work. I must use this.value in function itself and toString because otherwise the value is not bound to the object and subsequent MyString objects will overwrite this value.
                  • Stoyan Stefanov
                    How about using the Object() constructor as a factory to create a string object: var str = Object(Œsomestring¹); There¹s no `new` a.constructor.name ===
                    Message 9 of 15 , Feb 19, 2010
                    • 0 Attachment
                      How about using the Object() constructor as a factory to create a string
                      object:

                      var str = Object(Œsomestring¹);

                      There¹s no `new`

                      a.constructor.name === ³String² // true

                      Stoyan


                      On 2/17/10 4:21 AM, "Woomla" <woomla@...> wrote:

                      >
                      >
                      >
                      >
                      >
                      > jslint doesn't expect to see new String, but I need it because I want to
                      > set a property of the string:
                      >
                      > var str = new String('somestring');
                      > str.id = 123;
                      >
                      > Or is there another way to do this?
                      >
                      > [Non-text portions of this message have been removed]
                      >
                      >
                      >
                      >
                      >



                      [Non-text portions of this message have been removed]
                    • Jordan
                      Simply use: var str = String( blah ); to ensure that all of the String prototype s methods are applied. JSLint encourages this usage in this case. However,
                      Message 10 of 15 , Feb 19, 2010
                      • 0 Attachment
                        Simply use:
                        var str = String('blah');

                        to ensure that all of the String prototype's methods are applied. JSLint encourages this usage in this case.

                        However, rather than setting properties on strings, you might want to consider {str: 'string', id: 123} because then you're not dependent on the string being an object.

                        --- In jslint_com@yahoogroups.com, "Woomla" <woomla@...> wrote:
                        >
                        > jslint doesn't expect to see new String, but I need it because I want to
                        > set a property of the string:
                        >
                        > var str = new String('somestring');
                        > str.id = 123;
                        >
                        > Or is there another way to do this?
                        >
                        >
                        >
                        > [Non-text portions of this message have been removed]
                        >
                      Your message has been successfully submitted and would be delivered to recipients shortly.