2016-11-28 43 views
2

我只是想的东西,发现这个:String(number)在内部调用number.toString吗?

如果你打电话String(n)内定制toString,它调用本身并引发错误Maximum Call Stack exceeded

JSFiddle

Number.prototype.toString = function() { 
 
    return String(this) 
 
} 
 

 
var a = 10; 
 
try { 
 
    a.toString() 
 
} catch (err) { 
 
    console.log(err.message) 
 
}

但如果您直接拨打var b = String(a),则不会拨打toString功能。

JSFiddle

Number.prototype.toString = function(){ 
 
    console.log(this); 
 
    return '' + this; 
 
} 
 

 
var a = 10; 
 
a.toString();

注:我知道上面的代码中也抛出同样的错误,但我已经Nodechrome - JSFiddleFirefox - JSFiddle检查,这是一致的。 var b = String(a)不叫number.toString()'' + this也不叫。这是在栈片段中的一些优化,其在''+this上调用number.toString()

所以我的问题是,我错过了什么?为什么这种奇怪的行为?

+0

@Downvoters,我尊重你的观点,但如果你认为,什么是错的帖子,请分享您的评论。只是投票下来不会帮助任何人。 – Rajesh

回答

2

实际编号调用内部方法将其转换为字符串,其输出不受valueOftoString的影响,除非它们被明确调用。

那么为什么toString然后在第一个地方叫?

这是因为在“草率”(非严格)模式下,this值将被传递到或String(this)之前'' + this转化成它的对象的形式(即new Number(10)当量)。

(出于这个原因,你可能无法看到正常的应用这两种方式在使用严格模式之间的区别。)

由于this是一个对象,无论String()+加法运算符将尝试转换将该对象转换为字符串。这通常通过拨打obj.toStringobj.valueOf来完成。

至于为什么String(this)失败,但'' + this没有,String函数调用valueOf之前调用该对象的toString

但是,当您使用加法运算符(+)时,valueOftoString的顺序相反。

+0

不确定“*这个值将被转换为它的对象形式... *。我认为它是第二部分,'String(value)'将调用'value.toString',所以如果它的* toString *方法比调用* String *,发生递归,参见[* ECMA-262§21.1.1.1*](http://ecma-international.org/ecma-262/7.0/index.html#sec-string-constructor-string- value) – RobG

+0

@RobG:我的意思是'toString'首先被调用的原因是数字的对象形式为'String()',我会试着澄清我说过的话 –

+0

Cool实际上,阅读更加紧密,ECMA-262没有在[*算法中为ToString(number)*]指定调用toString(http://ecma-international.org/ecma-262/7.0/index.html#sec -tostring-applied-the-number-type),它可能就是它的实现方式 – RobG

0

可能你应该使用call/apply。

Number.prototype.toString = function() { 
 
    console.log(this) 
 
    return String(this) 
 
} 
 

 
var a = 10; 
 
try { 
 
    a.toString.call() 
 
    console.log(a) 
 
} catch (err) { 
 
    console.log(err.message) 
 
}

的原因,我认为是The reason to use JS .call() method?

+0

嘿,问题的目标是理解为什么会发生这种情况。同样只是一个指针,在没有'this'的情况下执行'.call'会清除上下文。 – Rajesh