2013-12-19 29 views
5

这已经变得更多的JavaScript的工作,而不是一个实际的问题要解决的思考。在一份声明中像自动javascript类型的强制

var str = 9 + " some words here"; 

的情况下得到的STR VAR将包含值“9一些话在这里”。我的问题是JavaScript使用什么函数将Number对象'9'自动强制为一个字符串与字符串对象“这里有些字”串联,并且此功能是可更改/可覆盖的。

这从我需要在页面上输出一个前面的0的单个数字开始。这是很容易的与Number对象

Number.prototype.SpecialFormat = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this.toString(); 
    } 
}; 

上快速原型函数来完成并配有简单的(9).SpecialFormat() + " words here";

调用它,但是让我知道如果我能覆盖上有一个号码的ToString函数

Number.prototype.toString = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this; 
    } 
}; 

,只是让JavaScript的自动转换处理它对于我来说,这样我就可以使用标准的9 + " words here";以“这里09字”得到同样的结果。这不只是隐含的工作,我不得不最终添加.toString到9 (9).toString() + " words here"(它进一步看,会导致一些无限循环)。

那么有没有办法来重写JavaScript本机类型的内置功能?

*注:我意识到这可能是一个 '最糟糕的想法永远'

+3

见[加法运算符(http://www.ecma-international.org/ecma-262/5.1/#sec-11.6 .1)(步骤7)以及[ToString](http://www.ecma-international.org/ecma-262/5.1/#sec-9.8)和“[ToString应用于数字类型](http ://www.ecma-international.org/ecma-262/5.1/#sec-9.8.1)”。看起来抽象操作'ToString(number)'从来没有使用'Number.prototype.toString'(事实上,这是另一种方式)。 – apsillers

+0

我想这就是为什么当我在toString原型中使用String(this)时出现“超出最大调用堆栈大小”错误的原因。 –

+0

我假设在这种情况下,JavaScript的构造方式与其他面向对象语言的构造方式不同,您可以重写应用于对象的运算符。在我看来,字符串连接是由解释器内部完成的,忽略了所有重写的方法。 – VisioN

回答

3

addition operator强求它的参数字符串步骤7:

  • 如果Type(lprim)为String或类型(rprim)是字符串,则
    • 返回串联ToString(lprim)后跟ToString(rprim)的字符串

ToString operation有编号的特殊规则,在 “ToString Applied to the Number Type” 详细说明。

看起来,抽象操作ToString(number)从未使用过Number.prototype.toString。事实上,ti是相反的:default Number.prototype.toString function采用了抽象的数字ToString算法。因此,无法在ECMAScript 5中的类型强制转换过程中重写数字串的默认行为,因为无法更改语言定义的ToString操作。

的ToString 强迫对象为字符串时使用目标的toString方法,而不是原始的编号值。

3

(不是严格意义上的答案,但我需要一些空间)

要非常小心的强制类型转换,结合原始类型与它们的目的同行尤其是因为:

var n = 9; 
typeof n; // "number" 
n instanceof Number; // false!! 

n = new Number(9); 
n instanceof Number; // true, oh thank God 
typeof n; // "object" what!! 

而且, toString on Number does not actually work:

Number.prototype.toString = function() { return "foo" + this; }; 
var n = new Number(9); 
"" + n; // "9", not "foo9" 

避免这种混乱的方法是通过具有:

var ns = { 
    number: { 
     specialFormat: function() /* .. */ } 
    } 
} 

ns.number.specialFormat(9); // "09" 
+0

'n =数字(9);'在第一个代码块中应该是'n = new Number(9);'。否则,您只需调用Number函数即可将该参数转换为数字原语,而原始数字原来就是这样。因此,它后面的两行将与之前的两行相同。 – Sam