当使用基本类型(字符串,数字)作为函数调用的this
主语(作为function.call()或函数apply()的第一个参数)时,似乎是原始类型被提升为等价的对象(例如,字符串变为字符串)。
举例说明:
var f = function(x) { return [typeof(this), typeof(x)]; }
var obj = '123'
f.call(obj, obj)
>>> ["object", "string"]
也就是说,“this”成为一个对象(它是一个String对象,我已经检查过),而第二个调用参数成为函数“f”的第一个参数,并且仍然是一个原始字符串。
对象 都是“123”,但微妙的东西不起作用(例如,它们在“==”方面相同,但在“===”方面则不相同)
我在chrome和firefox中都注意到了这种行为,所以我假设有一个特定的原因。我搜索过,但没有找到任何解释。我很感激任何解释,希望通过某种方式链接到文档,解释有关此规则及其发生原因的规则。
答案 0 :(得分:10)
这似乎是正确的行为。
<强> http://bclary.com/2004/11/07/#a-15.3.4.4 强>
Function.prototype.call - 被调用的函数作为此值传递 ToObject (thisArg)。
ToObject“根据以下内容将其参数转换为Object类型的值:
String - 创建一个新的String对象,其[[value]]属性设置为字符串的值。
答案 1 :(得分:2)
Javascript函数调用中的第一个参数&amp; Apply方法确定必须在哪个上下文中运行所请求的函数。 所以这将始终是一个对象
为了说明这一点,请查看以下示例
function totest()
{
this.ff = function(x) {
this.test(x);
};
this.test = function(x) {
alert(x);
}
}
function totest1()
{
this.test = function(x) {
alert(x);
}
}
function fun()
{
var obj = new totest();
var obj1 = new totest1();
obj.ff('hi'); //Runs fine without any problem
obj.ff.call(obj, 'sam') ; //Runs fine without any problem
obj.ff.call(this, 'sam'); //throws an error
obj.ff.call(obj1, 'sam'); //will be executed in the context of totest1
}
obj.ff.call(this,'sam')抛出错误。的 WHY 强>
因为我们指定obj.ff方法在fun(或这里的窗口)的上下文中执行,而不是在totest的上下文中。
obj.ff.call(obj1,'sam')告诉调用在totest1()的上下文中执行ff,并且它有效,因为它得到了方法测试。
所以这必须是对象。
调用方法中的剩余参数对于要执行的方法是真实的。所以他们会从给定的值推断出类型。
希望你现在能理解
答案 2 :(得分:0)
简短而简单:如果第一个参数属于基本类型,它将变成一个对象,因为正如您所指出的那样,它可能被调用函数中的this
引用。由于this
必须引用一个对象,运行时环境会确保 实际上是一个要引用的对象。想想你将如何实现它,你可能会得出同样的结论。好问题。
P.S。:我很欣赏Ramesh的答案,这在技术上是说明性的,但是想为不耐烦的读者添加一个答案。