Ужасно простой, но некорректный способ сделать это:
var MyString = function() {};
MyString.prototype = new String();
То, что вы просите, странно, потому что обычно в JS вы не рассматриваете их как строковые объекты, вы рассматриваете их как «строковые» типы, как примитивные значения. Кроме того, строки не являются изменяемыми вообще. Вы можете иметь любой объект , как если бы был строкой, указав .toString
метод:
var obj = {};
obj.toString = function() {
return this.value;
};
obj.value = 'hello';
console.log(obj + ' world!');
Но, очевидно, у него не было бы никаких строковых методов. Вы можете сделать наследование несколькими способами. Одним из них является «оригинальный» метод, который должен был использовать javascript, и который вы и я опубликовали выше, или:
var MyString = function() {};
var fn = function() {};
fn.prototype = String.prototype;
MyString.prototype = new fn();
Это позволяет добавлять в цепочку прототипов без вызова конструктора.
Путь ES5 будет:
MyString.prototype = Object.create(String.prototype, {
constructor: { value: MyString }
});
Нестандартный, но наиболее удобный способ:
MyString.prototype.__proto__ = String.prototype;
Итак, наконец, то, что вы могли бы сделать, это:
var MyString = function(str) {
this._value = str;
};
// non-standard, this is just an example
MyString.prototype.__proto__ = String.prototype;
MyString.prototype.toString = function() {
return this._value;
};
Унаследованные строковые методы могут работать с использованием этого метода, я не уверен. Я думаю, что они могли бы, потому что есть метод toString. Это зависит от того, как они реализованы внутри с помощью какого-либо конкретного механизма JS. Но они не могут. Вы должны были бы просто определить свой собственный. Еще раз, то, что вы просите, очень странно.
Вы также можете попробовать вызвать родительский конструктор напрямую:
var MyString = function(str) {
String.call(this, str);
};
MyString.prototype.__proto__ = String.prototype;
Но это тоже немного отрывочно.
Что бы вы ни пытались сделать с этим, вероятно, оно того не стоит. Могу поспорить, что есть лучший способ использовать то, для чего вы пытаетесь это использовать.
Если вы хотите абсолютно надежный способ сделать это:
// warning, not backwardly compatible with non-ES5 engines
var MyString = function(str) {
this._value = str;
};
Object.getOwnPropertyNames(String.prototype).forEach(function(key) {
var func = String.prototype[key];
MyString.prototype[key] = function() {
return func.apply(this._value, arguments);
};
});
Это будет карри this._value
для каждого метода String. Это будет интересно, потому что ваша строка будет изменчивой, в отличие от реальных строк JavaScript.
Вы могли бы сделать это:
return this._value = func.apply(this._value, arguments);
Что добавило бы интересную динамику. Если вы хотите, чтобы он возвращал одну из ваших строк вместо собственной строки:
return new MyString(func.apply(this._value, arguments));
Или просто:
this._value = func.apply(this._value, arguments);
return this;
Есть несколько способов справиться с этим в зависимости от желаемого поведения.
Кроме того, ваша строка не имеет длины или индексов, как строки javascript, способ решить эту проблему можно было бы вставить в конструктор:
var MyString = function(str) {
this._value = str;
this.length = str.length;
// very rough to instantiate
for (var i = 0, l = str.length; i < l; i++) {
this[i] = str[i];
}
};
Очень хакерский. В зависимости от реализации, вы можете просто вызывать конструктор для добавления индексов и длины. Вы также можете использовать геттер для длины, если вы хотите использовать ES5.
Еще раз, однако, то, что вы хотите сделать здесь, не является идеальным. Это будет медленно и не нужно.