Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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.

share|improve this question
 
You'll want to use prototypes. –  Shmiddty Jul 2 at 22:03
 
The length property should be read-only. –  Shmiddty Jul 2 at 22:08
 
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? –  hattenn Jul 2 at 22:10

1 Answer

up vote 2 down vote accepted

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];
}
share|improve this answer
 
Note: Be aware of the problem when using this[index], not supported in IE < 8, see string.charAt(x) or string[x]? –  Xotic750 Jul 4 at 13:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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