我知道我可以在一个对象上创建一个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/)
等具有相同的结果。
答案 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]
对象。因此,[它们]可以转移到其他类型的对象中用作方法。“您可以调用任何值,它们会强制将其强制为字符串(照常使用this
或String
。
您甚至不需要使用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(''));