【Web】浅析JQuery的apply(), call(), bind()方法

应和光
2023-12-01

由于在理解this的用法的时候多次出现了这几个方法,个人对这几个方法理解的不是很透彻,因此拿出来整理一下。关于this的用法,可移步至如下网址查看:
【Web】Javascript中的this陷阱(一)
http://blog.csdn.net/whuzxq/article/details/63265901
【Web】Javascript中的this陷阱(二)
http://blog.csdn.net/WHUZXQ/article/details/64142443


1.call()

语法:它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 

实例:

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.call(obj, "The color is ", "a very nice color indeed.");
//The color is blue, a very nice color indeed.

在这个例子中,函数 sayColor() 在对象外定义,即使它不属于任何对象,也可以引用关键字 this。对象 obj 的 color 属性等于 blue。调用 call() 方法时,第一个参数是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个和第三个参数是字符串。它们与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息 “The color is blue, a very nice color indeed.” 将被显示出来。

要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.call(this, sColor);

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

其他:
call 方法也可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

function Animal(name){      
    this.name = name;      
    this.showName = function(){      
        alert(this.name);      
    }      
}      

function Cat(name){    
    Animal.call(this, name);    
}      

var cat = new Cat("Black Cat");     
cat.showName();  

call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat。

2.apply()

语法:apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。

apply([thisObj[,argArray]]) 

先看一个实例:

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));

调用 apply() 方法时,第一个参数仍是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个参数是由两个字符串构成的数组,与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息仍是 “The color is blue, a very nice color indeed.”,将被显示出来。


小结:apply()和call()均是从ECMAScript 继承机制实现引申而来,因此理解好继承至关重要。

3.bind()

1..bind方法中的this

function f(){
return this.a;
}

var g=f.bind({a:test});//参数是一个对象,作为this
console.log(g());//test

var o={a:37,f:f,g:g};
console.log(o.f(),o.g());//37,test
//o.f():以对象属性调用,this指向o;o.g():虽然以对象的属性调用,但是仍然按照之前的绑定

2.bind方法

this.x=9;
var module={
x:81,
getX:function(){return this.x;}
};

module.getX();//81
var getX=module.getX;//赋值给变量,直接调用,this会指向全局对象,则返回9
getX();//9

var boundGetX=getX.bind(module);//绑定module对象
boundGetX();//81

3.bind的科里化

function add(a,b,c){

return a+b+c;
}

var func=add.bind(undefind,100);//无需指定传入的对象,但是指定了一个参数为100,那么a将赋值100
func(1,2)//103

var func2=func.bind(undefined,200);//因为a已经被指定,因此将b指定为200
func2(10);310

4.bind与new

function foo(){
this.b=100;//直接调用的话,则创建全局对象b
return this.a;
}

var func=foo.bind({a:1});
func();//1
new func();//{b:100}  使用new的话,将会把this作为返回值,并且this会被初始化为一个默认的空对象,该空对象的原型指向foo.prototype.即使用了bind,也无法指向指定对象。return this.a将会被忽略。

5.bind方法模拟
bind作用:绑定this+科里化

Function.prototype.bind=function(oThis){
if(typeof this !=='function'){//同过对象.方法调用的方式,那么this将指向一个函数
 throw new TypeError("error");
}

var aArgs=Array.prototype.slice.call(arguments,1),//通过argument获取其他的参数,由于arguments不是数组,因此通过以上方式使用slice方法,忽略掉第一个参数,从第二个参数往后获取。
fToBind=this,
fNOP=function(){},
fBound=function(){
return fToBind.apply(this.instanceof fNOP? this:oThis,aArgs.concat(Arrat.prototype.slice.call(arguments)));

fNOP.prototype=this.prototype;
fBound.prototype=new fNOP();

return fBound;

}


}

用法:小白一枚,这篇教程就点到为止,更加详细的使用方法详见[http://blog.liuwanlin.info/javascriptzhong-bindfang-fa-de-shi-xian/]
先MARK,明天继续看。

 类似资料: