是否可以在JavaScript中自动进行字符串化?

时间:2018-12-17 06:30:26

标签: 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.lengthobjInstance.match(/something/)等具有相同的结果。

3 个答案:

答案 0 :(得分:30)

您可以让您的对象继承自public ExecuteStrategy(MethodInfo command, Type canExecuteType) { Command = command; CanExecuteType = canExecuteType; CanExecute = CanExecuteType.GetMethod("CanExecute"); } public void Execute(object message) { CanExecute.Invoke(CanExecuteType, new[] { message }); } ,以便所有字符串方法都可用:

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(""));解决方案:-)

所有Proxy方法(String.prototype.toString.valueOf除外)都是“ 故意通用的; [它们]不需要其{{ 1}}值是[Symbol.iterator]对象。因此,[它们]可以转移到其他类型的对象中用作方法。“您可以调用任何值,它们会强制将其强制为字符串(照常使用thisString

您甚至不需要使用ES6 .toString()从内置继承(这也使您的字符串值不可变)继承,它也可以在ES5中使用:

.valueOf

答案 1 :(得分:23)

一种选择是返回一个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);

答案 2 :(得分: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(''));

在评论中您已经询问:

  

我当时正在考虑通过对所有功能进行编程来实现此目的-但是有办法列出对象的所有功能吗?

是的,您可以在getOwnPropertyNames上使用String.prototype并过滤掉那些无效的函数:

var SomeObject = function(a, b){
    this.a = a;
    this.b = b
}

SomeObject.prototype.toString = function(){
    return [ this.a, this.b ].join(' ')
};

Object.getOwnPropertyNames(String.prototype).forEach(function(name) {
    var fn = String.prototype[name];
    if (name !== "toString" && typeof fn === "function") {
        SomeObject.prototype[name] = function() {
            return fn.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(''));