0

I was wondering if it's possible to attach a method to a primitive (e.g., a string) while still being able to use it as the primitive. Note: this is different from adding methods to the String class as described in other questions (e.g., Extend a String class in ES6).

For instance, here's some dummy code of what I've been trying. Essentially, I could wrap the primitive in a class, add methods to that class, the somehow still be able to access the underlying value automatically?

class MyString {
    value: string

    constructor(value) {
        this.value = value
    }

    get5thCharacter() {
        return this.value[4]
    }
}

const hello = new MyString("hello")
const world = "world"

// desired results
console.log(hello + " " + world) // "hello world"
console.log(hello.get5thCharacter()) // "o"
console.log(world.get5thCharacter()) // TypeError: world.get5thCharacter is not a function

Notice also that while world is also a String, world does not have the method I defined on hello, despite the fact they can both otherwise be used as strings.

Any thoughts?

Nick
  • 5,108
  • 2
  • 25
  • 58
  • It should be `this.value[4]`. Additionally, you haven't defined `toString`, so the output for the first `console.log` would not be `"hello world"`. – Unmitigated Jan 14 '23 at 17:40
  • Thanks. Fixed the this.value[4] and tried to make it clearer that those comments are my desired results, not the actual ones from this code snippet. – Nick Jan 14 '23 at 17:42
  • Does this answer your question? [Extend a String class in ES6](https://stackoverflow.com/questions/30257915/extend-a-string-class-in-es6) – pilchard Jan 14 '23 at 17:52
  • also [How to correctly inherit from String built-in class](https://stackoverflow.com/questions/46992393/how-to-correctly-inherit-from-string-built-in-class) – pilchard Jan 14 '23 at 17:53
  • No the "Extend a String class in ES6" question doesn't answer it because it mutates the prototype of all strings. Therefore all strings will have that new method. I only want specific strings to have the new method. That's why the last console.log should fail. If I instead attached the function to the string's prototype as that other question suggested, that last console.log would print "d". – Nick Jan 14 '23 at 17:57

2 Answers2

2

After playing aroudn with Konrad's answer, I think I found the solution. By extending the primitive type it still acts like that primitive. You can also still access methods and properties of the original.

class MyString extends String {
  constructor(value) {
super(value);
this.value = value;
  }

  get5thCharacter() {
return this.value[4];
  }
}

const hello = new MyString("hello");
const world = "world";

console.log(hello + " " + world); // "hello world"
console.log(hello.length);
console.log(world.length);
console.log(hello.get5thCharacter()); // "o"
console.log(world.get5thCharacter()); // TypeError: world.get5thCharacter is not a function
Nick
  • 5,108
  • 2
  • 25
  • 58
0

class MyString {
  constructor(value) {
    this.value = value
  }

  get5thCharacter() {
    return this.value[4]
  }

  toString() {
    return this.value
  }
}

const hello = new MyString("hello")
const world = "world"

console.log(hello + " " + world) // "hello world"
console.log(hello.get5thCharacter()) // "o"
console.log(world.get5thCharacter()) // TypeError: world.get5thCharacter is not a function
Konrad
  • 21,590
  • 4
  • 28
  • 64