日期:2014-05-16  浏览次数:20332 次

Javascript中call的使用

貌似理解了?http://hszy00232.blog.163.com/blog/static/43022753201131835653841/

?

?

6.不错,接下来再理解一个怪异的形式

示例10:

?

function f1(){
    alert(1);
}
function f2(){
    alert(2)
}
var f3 = f1.call;
f1.call(f2);//1
f3.call(f2);//2


?

f1.call(f2);比较好理解,如果不理解看上边的case,但如何理解f3.call(f2)会返回2呢,为了方便理解进行一下等效变化为f1.call.call(f2),这时会发现实际上是f1.call方法call调用了f2,那f1怎么又会有call方法呢?call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性。

在理解f1.call.call(f2)时我们首先要知道call方法到底是如何执行的,这样才能f1.call.call(f2)如何执行。

示例11:

引用JK写的一个用apply实现call的方法:

?

function jsCall(oThis){//这里的jsCall就是Call
    var argsNew = [];
    for(var i=1;i<arguments.length;i++){
        argsNew.push(arguments[i]);
    }
    return this.apply(oThis,argsNew);
}
Function.prototype.jsCall = jsCall;

?

或简写成

?

function jsCall(oThis){//这里的jsCall就是Call
    var argsNew = [].slice.call(arguments,1)    
    return this.apply(oThis,argsNew);
Function.prototype.jsCall = jsCall;

?

?

这样就得到了一个和call一样功能的jsCall.

接下来构建两个函数f1,f2

?

function f1(a){
    alert([this,a,'f1']);
}
f1(11);//[object Window],11,f1
function f2(a){
    alert([this,a,'f2']);
}
f2(22);//[object Window],11,f2

?

用jsCall把f1中的this替换成f2

?

function f1(a){
    alert([this,a,'f1']);
}
function f2(a){
    alert([this,a,'f2']);
}
f1.jsCall(f2,11);//function f2(a){alert([this, a, "f2"]);},11,f1

?

function jsCall(oThis){//这里的jsCall就是Call
    var argsNew = [].slice.call(arguments,1)    
    return this.apply(oThis,argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a){
    alert([this,a,'f1']);
}
function f2(a){
    alert([this,a,'f2']);
} 
f1.jsCall.jsCall(f2,11);//11,,f2

?

在执行f1.jsCall.jsCall(f2,11);时返回11,,f2,为什么会返回这个结果,重点来了:)

f1.jsCall方法:

?

alert(f1.jsCall);
//返回
//function jsCall(oThis) {
//    var argsNew = [].slice.call(arguments, 1);
//    return this.apply(oThis, argsNew);
//}

?

所以f1.jsCall.jsCall可以替换成jsCall.jsCall看一下执行结果

?

function jsCall(oThis){//这里的jsCall就是Call
    var argsNew = [].slice.call(arguments,1)    
    return this.apply(oThis,argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a){
    alert([this,a,'f1']);
}
function f2(a){
    alert([this,a,'f2']);
}
jsCall.jsCall(f2,11);//11,,f2
?

接着分析

jsCall在执行的过程中,return this.apply(oThis,argsNew);里的this被替换成了f2,11做为参数传给了(oThis,argsNew),变成了f2.apply(11);

?

function jsCall(oThis){//这里的jsCall就是Call
    var argsNew = [].slice.call(arguments,1)    
    return this.apply(oThis,argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a){
    alert([this,a,'f1']);
}
function f2(a){
    alert([this,a,'f2']);
}
f2.apply(11);//11,,f2
?

返回结果跟f1.jsCall.jsCall(f2,11)一样。

回过头来看

?

function f1(){
    alert(1);
}
function f2(){
    alert(2)
}
var f3 = f1.call;
f1.call(f2);//1
f3.call(f2);//2
?

这样就不难理解f1.call.call(f2)实现时,f1.call执行过程中call中的this被f2替换成了f2.call();因为f2里没有this的引用所以执行结果是2.

f2.call()//2

需要十分注意的是f1.call是方法,f1是函数对象,这两者在call时是有区别的。

------------------------------------------我的理解----------------------------------------------

?

function flower(){
    this.pollen="花粉";
	this.petal=function(){//花瓣
		console.log("leaf and bud"+this.pollen);
	};
}
function flower2(){}
var seed=new flower();
var seed2=new flower2();
var tree={};
//小蜜蜂call花flower花flower2种子seed种子seed2树tree
//盛开