为什么javascript在传递给function.apply()或function.call()时会改变原始类型?

时间:2010-02-19 08:13:19

标签: javascript

当使用基本类型(字符串,数字)作为函数调用的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中都注意到了这种行为,所以我假设有一个特定的原因。我搜索过,但没有找到任何解释。我很感激任何解释,希望通过某种方式链接到文档,解释有关此规则及其发生原因的规则。

3 个答案:

答案 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的答案,这在技术上是说明性的,但是想为不耐烦的读者添加一个答案。