1
\$\begingroup\$

I am reading "Object-Oriented JavaScript" by Stoyan Stefanov to learn JavaScript and in the end of the chapter named "Objects", there's an exercise that asks you to implement your own String object. I have implemented some methods of String (not all), I'd be happy if you could check and let me know how it could be done better:

function MyString(primitive) {
    this.length = 0;
    var i = 0;
    // Here length is calculated and the indexer is set.
    for (var c in primitive) {
        this[i++] = primitive[c];
        this.length++;
    }

    this.toString = function() { return primitive; };
    this.valueOf = this.toString;
    this.substring = function(start, end) {
        var result = '';

        // Edge cases for the parameters.
        if ((typeof end !== 'number' && typeof parseInt(end) !== 'number') || end > this.length)
            end = this.length;
        if (end <= 0 || isNaN(end)) {
            end = start;
            start = 0;
        }

        for (var i = start; i < end; i++) {
            result += this[i];
        }

        return result;
    }
    this.charAt = function(i) {
        var x = parseInt(i);
        x = isNaN(x) ? 0 : x;
        return this.substring(x, x+1);
    };

    return this;
}

var s = new MyString('hello');
console.log(s.length);
console.log(s[0]);
console.log(s.toString());
console.log(s.valueOf());
console.log(s.charAt(1));
console.log(s.charAt('2'));
console.log(s.charAt('e'));
console.log(s.substring(1, 3));

Any and all suggestions are welcome. I'm completely new to JavaScript and would love to hear my mistakes.

\$\endgroup\$
3
  • \$\begingroup\$ You'll want to use prototypes. \$\endgroup\$
    – Shmiddty
    Jul 2, 2013 at 22:03
  • \$\begingroup\$ The length property should be read-only. \$\endgroup\$
    – Shmiddty
    Jul 2, 2013 at 22:08
  • \$\begingroup\$ I know it should be read-only but I have no idea at the moment how to make it so. And the prototypes chapter is the next one (I'm reading it now). Could you add an answer with your suggested improvements? \$\endgroup\$
    – hattenn
    Jul 2, 2013 at 22:10

1 Answer 1

2
\$\begingroup\$

Some information up front:

  1. Object.defineProperty is an Ecmascript 5 feature, and is not available in older browsers (IE < 9).

  2. There is likely a cleaner way of doing all of this.

This is a basic skeleton:

function MyString(primitive) {
    var length = 0, a;   // private internal variable to track length, and our iterator

    // the loop below basically ensures that this string object is immutable. 
    for(a in primitive){
        (function(char){
            Object.defineProperty(this, length++, {
                get:function(){return char;}
            });
        }).call(this,primitive[a]);
    }

    // we can "get" the length, but we can't "set" it.
    Object.defineProperty(this, "length", {
        get:function(){return length;}
    });

    return this;
}

// defining methods on the prototype of an object allows us to share the same instance 
// of the method without recreating it for each instance of the object. 
// (reduced memory footprint)
MyString.prototype.toString = function(){
    return [].join.call(this, '');  
    // since our object is "array-like", we can use array methods on it. 
}

MyString.prototype.charAt = function(index){
    return this[index];
}
\$\endgroup\$
2
  • \$\begingroup\$ Note: Be aware of the problem when using this[index], not supported in IE < 8, see string.charAt(x) or string[x]? \$\endgroup\$
    – Xotic750
    Jul 4, 2013 at 13:22
  • \$\begingroup\$ @Xotic750 This is true but in this case it should work since he is not accessing the string but the MyString object which has an internal 0: 'a' etc representations \$\endgroup\$
    – Haagenti
    Jan 6, 2015 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.