Можно ли автоматически переводить строки в JavaScript?
Я знаю, что могу создать функцию toString()
для объекта, чтобы каждый раз, когда он печатался или обрабатывался как строка, он сначала приводил в соответствие объект с этой функцией.
Можно ли сделать это напрямую, чтобы я мог использовать функции объекта String для объекта?
var SomeObject = function(a, b){
this.a = a;
this.b = b
}
SomeObject.prototype.toString = function(){
return [ this.a, this.b ].join(' ')
}
var objInstance = new SomeObject('this', 'that');
console.log(objInstance + '') // this that
console.log(("" + objInstance).split('')) // [ 't', 'h', 'i', 's', ' ', 't', 'h', 'a', 't' ]
console.log(objInstance.split()) // error
Можно ли сделать так, чтобы объект "вел себя" как строка, когда к нему вызывается функция String?
Другими словами, я бы хотел, чтобы objInstance.split()
имел тот же результат, что и ("" + objInstance).split('')
, а также objInstance.length
или objInstance.match(/something/)
и т.д. И т.д. И т.д.
Ответы
Ответ 1
Вы можете позволить своим объектам наследоваться от String
чтобы все строковые методы стали доступны:
class SomeObject extends String {
constructor(a, b) {
super(a + " " + b);
this.a = a;
this.b = b;
}
}
var obj = new SomeObject('this', 'that');
console.log(obj.split(""));
Ответ 2
Один из вариантов - вернуть Proxy
который проверяет, существует ли свойство в String.prototype
, и, если это так, вызывает это свойство со строкой, представляющей объект:
// Declare the proxy handler up front here
// to avoid unnecessary creation of duplicate handler objects
const handler = {
get(obj, prop) {
if (obj[prop] !== undefined) {
return obj[prop];
}
const stringMethod = String.prototype[prop];
if (stringMethod) {
return stringMethod.bind(obj.a + ' ' + obj.b);
}
},
};
const SomeClass = function(a, b) {
this.a = a;
this.b = b
return new Proxy(this, handler);
}
const instance = new SomeClass('this', 'that');
// String methods:
console.log(instance.trim());
console.log(instance.includes('this'));
console.log(instance.includes('somethingelse'));
console.log(instance.split(''));
// Can still assign and retrieve values directly on the object as normal:
instance.foo = 'foo';
console.log(instance.foo);
Ответ 3
Один из вариантов расширения SomeObject
, что-то вроде этого.
var SomeObject = function(a, b){
this.a = a;
this.b = b
}
SomeObject.prototype.toString = function(){
return [ this.a, this.b ].join(' ')
};
SomeObject.prototype.split = function() {
return String.prototype.split.apply(this.toString(), arguments);
};
var objInstance = new SomeObject('this', 'that');
console.log(objInstance + '') // this that
//console.log(("" + objInstance).split('')) // [ 't', 'h', 'i', 's', ' ', 't', 'h', 'a', 't' ]
console.log(objInstance.split(''));
Ответ 4
Если я правильно понимаю, вы можете использовать синтаксис распространения для достижения этой цели
let a = 'this'; let b = 'that';
const merged = [...a, ...b];
console.log({merged});