今天看重看jquery源码时候,想到一个关于js里面call()问题。网络上常用的解释call的代码如下:function Animal(){  
    this.name = "Animal";  
    this.showName = function(){  
        alert(this.name);  
    }  
}  
/**定义一个Cat类*/  
function Cat(){  
    this.name = "Cat";  
}  
  
/**创建两个类对象*/  
var animal = new Animal();  
var cat = new Cat();  
  
//通过call或apply方法,将原本属于Animal对象的showName()方法交给当前对象cat来使用了。  
//输入结果为"Cat"  
animal.showName.call(cat,",");  
//animal.showName.apply(cat,[]); 这样的代码和我以前一直的理解也都是一样的。我以前一直这样理解call或者apply的方法  animal.showName.call(cat,","); 其实也就是将showName里面的this本来是指向animal,call调用后this指向cat。
这样理解,也就能解释了。 
但是今天搜索资料时候看到别人另外一段demo:   function add(a,b) 

alert(a+b); 

function sub(a,b) 

alert(a-b); 

add.call(sub,3,1); //4为了理解上面这个demo我重新修改了一些: var test =  111;
function _add()  
{  
   // this.test = 444;  //注释①
    alert(this.test);  
}  
function _sub()  
{  
    this.test = 222;
    alert(this.test);  
}  
  _add();           
  _sub();
_add.call(_sub);   //未去掉注释①:undefined  去掉:444
var d = new _add();//结果等同于_add.call(_sub);  那我就不明白了啊。
1.
 _add.call(_sub)
 _add.call(_sub) = window._add.call(_sub),this开始是指向window的,call掉用后为什么就又指向哪里去了呢?
2.
 _add.call(new _sub())如果这样写得话呢,那很明显结果this是指向 _sub的对象的,
 但是,我们又常说JS里面的方法(function)也是对象,那么是不是说
_add.call(_sub) 等于如下代码:   var _sub = new function (){
       this.test = 222;
       alert(this.test);  
   }
   _add.call(_sub)//2223.那为什么以上1和2的返回值是不一样的呢?一个是undefined,一个是222
PS:现在是感觉就差那么一点点就懂了。但是就是一想多了深了就又糊涂了,求大神指点啊。

解决方案 »

  1.   


    var f1=function(){this.a='类f1的实例的a属性'};
    f1.a='对象f1的a属性';
    var f2=function(){};//类f2的实例没有a属性
    f2.a='对象f2的a属性';
    var test=function(){alert(this.a)};
    test.call(f1);//弹出'对象f1的a属性'
    test.call(new f1());//弹出'类f1的实例的a属性'
    test.call(f2);//弹出'对象f2的a属性'
    test.call(new f2());//弹出undefined解释:call和apply函数只是单纯地把调用的方法中的this指向了第一个参数,从第二个参数开始为传递到调用方法的参数test.call(f1);//==>test=function(){alert(this.a);}this指向对象f1
    test.call(new f1());//==>test=function(){alert(this.a);}this指向类f1的实例
      

  2.   

    没注释 第一个注释var test = 111;
    function _add()  
    {  
        this.test = 444;  //注释①
        alert(this.test);  
    }  
    function _sub()
    {  
        this.test = 222;
        alert(this.test);  
    }  
    _add();//弹出444          
    _sub();//弹出222
    _add.call(_sub);
    /*
    _add.call(_sub)的执行效果:执行_add函数,函数体中的this指向_sub
    结果:
    1.函数_sub有一个test属性,即_sub.test=444;
    2._add中alert(this.test)中的this指向_sub,弹出444
    */ 
    alert(_sub.test);注释第一个注释后var test = 111;
    function _add()  
    {  
        //this.test = 444;  //注释①
        alert(this.test);  
    }  
    function _sub()
    {  
        this.test = 222;
        alert(this.test);  
    }  
    _add();//弹出111,_add中this指向window      
    var d=new _sub();//_sub中this指向d
    alert(test);//弹出111  !!!!!!!!
    _sub();//弹出222,_sub中的this继续指向window
    alert(test);//执行_sub()的结果!!!!!!!!
    _add.call(_sub);//_add中this指向_sub,_sub无test属性,undefined注意打了感叹号的两个弹出
      

  3.   

    _add.call(_sub);//_add中this指向_sub,_sub无test属性,undefined
    如果this指向_的话sub,为什么//this.test = 444;  //注释① 这个注释去掉,_add.call(_sub);会弹出444呢?
      

  4.   


    var test = 111;
    function _add()  
    {  
        this.test = 444;  //注释①
        this();
        alert(this.test);  
    }  
    function _sub()
    {  
        this.test = 222;
        alert(this.test);  
    }  
    _add.call(_sub);
    /*
    _add.call(_sub)的执行效果:执行_add函数,函数体中的this指向_sub,_sub是个函数对象,它也有它的属性
    结果:
    _add.call(_sub);
    function _add()  
    {  
        alert(window.test);//弹出111,与alert(test)一样
        this.test = 444;  //注释① this指向_sub,为_sub添加了一个test属性,值为444
        this();//this指向_sub,执行_sub方法,在_sub方法中,_sub中的this指向window
        alert(window.test);//上一句的效果,与alert(test)一样
        alert(this.test); //上一句代码为_sub添加test属性,这里等价于alert(_sub.test);弹出444
    }
    */ 注意,在_add中有一句this();假使call的时候调用的不是一个函数对象将出错