您的位置:首页 > 移动开发

JS中call和apply的用法

2016-08-29 14:45 330 查看
先看一下js中对call的解释

语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])

  参数 thisObj 可选项。将被用作当前对象的对象。 arg1, arg2, , argN 可选项。将被传递方法参数序列。

  说明
  call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
  如果没有提供 thisObj 参数,那么 Global 对象被用作thisObj。

说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。

好吧,话不多说,上个例子看

function Cat(name, type) {
this.type = type;
this.name = name;
}

Cat.prototype.say = function() {
console.log("I'm " + this.type + ",my name is " + this.name);
}

Cat.prototype.eat = function() {
console.log("I'm " + this.name + ",I eat bread and drink milk");
}

Cat.prototype.sleep = function() {
console.log("I'm " + this.name + ",I sleep in bed");
}

var cat = new Cat("Tom", "cat");
cat.say();//I'm cat,my name is Tom
cat.eat();//I'm Tom,I eat bread and drink milk
cat.sleep();//I'm Tom,I sleep in bed

这个很明显,new一个Cat,调用cat的say各个方法,这个没什么可说的

OK。

有了Tom猫,如果没有Jerry,岂不是很无聊

于是Jerry就出来了

function Mouse(name, type) {
this.type = type;
this.name = name;
}

Mouse.prototype.say = function() {
console.log("I'm " + this.type + ",my name is " + this.name);
}

Mouse.prototype.eat = function() {
console.log("I'm " + this.name + ",I eat bread and drink milk");
}

Mouse.prototype.sleep = function() {
console.log("I'm " + this.name + ",I sleep in bed");
}

var mouse = new Mouse("Jerry", "Mouse");
mouse.say();//I'm Mouse,my name is Jerry
cat.eat();//I'm Jerry,I eat bread and drink milk
cat.sleep();//I'm Jerry,I sleep in bed

好的,现在Jerry也来了,和Tom愉快的玩耍

等等!!!

是不是感觉这两段代码,尤其是Tom和Jerry说话,吃东西、睡觉部分的代码太重复了

现在,一猫一鼠来到动物园入住了,3000中动物一块说、吃、睡,重复写3000次吗?

幸好,幸好我们还有call(怎么读起来像是,想好我们还有靠!)

直接看代码吧

function Cat(name, type) {
this.type = type;
this.name = name;
}
Cat.prototype.say = function() {
console.log("I'm " + this.type + ",my name is " + this.name);
}

Cat.prototype.eat = function() {
console.log("I'm " + this.name + ",I eat bread and drink milk");
}

Cat.prototype.sleep = function() {
console.log("I'm " + this.name +",I sleep in bed");
}

function Mouse(name, type) {
this.type = type;
this.name = name;
}

var cat = new Cat("Tom", "cat");

cat.say();//I'm cat,my name is Tom

cat.eat();//I eat bread and drink milk

cat.sleep();//I sleep in bed

var mouse = new Mouse("Jerry","mouse");

cat.say.call(mouse);//I'm mouse,my name is Jerry

cat.eat.call(mouse);//I'm Jerry,I eat bread and drink milk

cat.sleep.call(mouse);//I'm Jerry,I sleep in bed

就是这样。

在代码中,我用cat(new出来的汤姆)调用say方法,在call中传入mouse(new出来的杰瑞),

此时,就变成了,杰瑞去say()。

也就是说,用杰瑞调用了say方法

可是杰瑞没有say方法啊,Mouse并没有定义say方法。

这就是call神奇的地方了

js手册中的说明:

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

也就是说,在这里用了call,就意味着用杰瑞来代替汤姆调用say方法,call将say方法的对象上下文(也就是this)从汤姆变成杰瑞了。

———————————————————————————————————————————————

说完call,说一下apply吧

其实呢,apply的作用和call是一样的

不同之处就在于apply接收的后一个参数是数组

——————————————————————————————————————————————

举个例子,给Cat添加一个方法

Cat.prototype.sport = function(where,what) {
console.log("I'm " + this.name + ",and I'm in " + where +",and play " + what);
}

cat.sport("beijing","basketball");//I'm Tom,and I'm in beijing,and play basketball

在这里,如果用call的话,就是这样

cat.sport.call(mouse,"beijing","basketball");//I'm Jerry,and I'm in beijing,and play basketball

如果改用apply的话呢,就是这样

cat.sport.apply(mouse,["beijing","basketball"]);//I'm Jerry,and I'm in beijing,and play basketball

就是把后面的参数,放在数组里,这种形式,在jquery的一些插件中挺常见的



比如在jqgrid中,就是将用户传进来的参数pin,从第二位开始,转成数组,同时作为apply调用时的参数

如果在这个地方用call的话,由于用户传入参数个数不固定,因此不能确定call中参数个数,

但如果用apply的话,传入数组就可以啦!!!

由于本人水平有限,文中不足之处,请各位于评论中之处,3Q
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript call apply