【问题标题】:Why toString is not a generic function in javascript为什么 toString 不是 javascript 中的通用函数
【发布时间】:2026-02-16 19:55:02
【问题描述】:

我试图做这样的事情。

 var myFunc = function() {}
 myFunc.prototype = new String();
 myFunc.prototype.replace = function() {return 'hii, Mr '+ this.toString();}       

 var oVal = new myFunc('Jyotirmay');
 oVal.replace();

o/p :: Uncaught TypeError: String.prototype.toString is not generic(…)

为什么“function not generic”错误实际上普遍出现?

为了更清楚,我如何将我的论点(即 Jyotirmay)从继承的类传递给基类,即字符串。这样我就可以通过调用任何适当的字符串函数来获得该值。

我不想通过处理函数中的变量来从函数中获取传递的值。 我希望由父类处理。你可以用其他语言说 super()。

【问题讨论】:

  • *.com/questions/16937940/… 看看这个答案。 :)
  • @Gaurav,在问这个问题之前先检查一下,因为我没有从那个帖子中得到我的解决方案。无论如何thanx :)
  • 您实际上在问什么?帮助您的代码或为什么toString 不是通用的?
  • @Xotic750 两个都可以回答。
  • 您是在尝试使用自己的方法创建自己的原型对象,还是实际上在尝试创建String 的子类并覆盖replace 方法?不清楚。

标签: javascript oop inheritance


【解决方案1】:

目前尚不清楚您究竟想从您的问题和 cmets 中实现什么,但也许这就是您想要做的全部?

function myFunc(inputArg) {
    this.inputArg = inputArg;
}

myFunc.prototype = {
    replace: function () {
        return 'hii, Mr ' + this.inputArg;
    },
    
    toString: function () {
        return '' + this.inputArg;
    }
};

myFunc.prototype.valueOf = myFunc.prototype.toString;

function log(inputArg) {
    document.getElementById('out').appendChild(document.createTextNode(inputArg + '\n'));
}

var oVal = new myFunc('Jyotirmay');

log(oVal);
log(oVal.replace());
<pre id="out"></pre>

对于Why is toString not generic,这是因为不是所有的对象都可以用相同的转换方法表示为字符串。

根据您的最新评论进行更新

众所周知,原生对象很难(如果不是不可能的话)在 Javascript 中进行子类化。有一些技巧可以让你取得部分成功,但我不推荐它们,祝你在不同环境中好运。

两个(但不是唯一的)这样的黑客是:

窃取iframe

function stealObject(objectName, myVariableName) {
    var iframe = document.createElement('iframe');

    iframe.style.display = 'none';
    iframe.src = 'javascript:parent.' + myVariableName + ' = ' + objectName;
    document.body.appendChild(iframe);
    document.body.removeChild(iframe);

    return window[myVariableName];
}

function log(inputArg) {
    document.getElementById('out').appendChild(document.createTextNode(inputArg + '\n'));
}

try {
    stealObject('String', 'MyString');
    MyString.prototype.replace = function () {
        return 'hii, Mr ' + this;
    };


    var oVal = new MyString('Jyotirmay');

    log(oVal);
    log(oVal.toUpperCase());
    log(oVal.replace());
} catch (e) {
    log(e);
}
<pre id="out"></pre>

在 SO sn-ps 中不起作用,因为 SecurityError: Sandbox access violation: 但可以在此 jsFiddle 上看到它。 typeof oVal 将返回 object 而不是 stringoVal instanceof String 将是 falseoVal.constructor === String 将返回 false

另一个黑客

function MyString() {
    this.str = '' + arguments[0];
};

with(MyString.prototype = new String()) {
    toString = valueOf = function () {
        return this.str;
    };
}

MyString.prototype.replace = function () {
    return 'hii, Mr ' + this;
};

function log(inputArg) {
    document.getElementById('out').appendChild(document.createTextNode(inputArg + '\n'));
}

var oVal = new MyString('Jyotirmay');

log(oVal);
log(oVal.toUpperCase());
log(oVal.replace());
<pre id="out"></pre>

神奇的length 属性在这个属性中被破坏了,您需要调用oVal.toString().lengthtypeof oVal 将返回 object 而不是 stringoVal instanceof String 将是 trueoVal.constructor === String 将返回 true

【讨论】:

  • 更新了问题。希望你现在能清楚地看到。我希望字符串来处理我传递的参数,而不是我自己的函数。就像一个超级()。 ??
  • 我不敢相信你可以在从另一个域加载的 iframe 中执行任意代码,只需将其 src 设置为“javascript:”......这在现代浏览器中有效吗??