JS call和apply的用法

在js中,call和apply是每个函数都有非继承而来的方法,主要作用是在指定的作用域内调用函数,实际是指定函数内的this对象的值。

他们的区别是,function.call(objec,param1,param2......),call 的第二个参数之后的参数(包含第二个参数)实际是个有序的参数列表,

而 function.apply(object, paramsArr), apply的第二个参数是数组形式或者对象的。

那么他们的主要用途:有三点

1. 在指定作用域中调用函数:

例如:

a. 基本用法的简单用例:

function Cat(){
this.name="white cat";
}
Cat.prototype.say=function(){
alert(this.name);
};
var dog={name:'a yellow dog'};
Cat.prototype.say.call(dog);或者 Cat.prototype.say.apply(dog);

在方法Cat.prototype.say中指定 this=dog,结果为 'a yellow dog‘

b.其实这种用法在 实现寄身组合式继承的时候也有用到,因为在继承时,子类需要实现父类的构造方法:

function Super(strength,intelligence,agility,message){
this.strength=strength;
this.intelligence=intelligence;
this.agility=agility;
this.message=message;
}
Super.prototype.say=function(){
alert("A fresh meat!");
};
function extend(sub,super){
var prototype=Object.create(super.prototype);
prototype.constructor=sub;
sub.prototype=prototype;
};//在继承这一步时,原型的构造函数只是变成了sub,那么这一步结束时,sub并未拥有super类的构造函数。
function Sub(){
Super.apply(this,argument); //在这里,apply指定this=Sub, 执行Super方法,这才真正拥有了Super类的构造函数。
}
extend(Sub,Super); //实现完整的继承

2. 充分利用apply的隐藏特性:自动将array类型或者object类型的参数转换为所调用方法的参数列表

a. Math.min(param1,param2,param3...........),

var arr=[1,2,3,4,5];
Math.min.apply(null,arr); //1
Math.min(1,2,3,4,5);//1

Math.max.apply(null,arr); //5
Math.max(1,2,3,4,5);  //5

b. Array.prototype.push(param1,param2...........);

利用apply合并两个数组

var arr1=[1,2,3];
var arr2=[4,5,6];
Array.prototype.push.apply(arr1,arr2); // [1,2,3,4,5,6]

3. 结合call/apply 和 Array.prototype.slice, 让类数组对象或者集合拥有Array对象所拥有的方法。

(所谓的“类数组对象”或者集合:以0开头的连续自然数为属性名,拥有length属性,且值为自然数属性名的长度)

例如:

var a = {0: 'x', 1: 'y', 2: 'z', 3: 'e', length: 4};
var b = Array.prototype.slice.apply(a);
console.log(b); //["x", "y", "z", "e"]
console.log(b instanceof Array); //true

a. Array.prototype.slice();

function list(){ 
console.log(arguments.length); 
return Array.prototype.slice.call(arguments); 
} 
var list1=list(1,2,3,4,5); //这时,list1对象拥有了Array的所有方法了, arguments.length 5
list1.push(6);

b. 让dom元素集合拥有Array下的方法

var domlist = Array.prototype.slice.call(document.getElementsByTagName("*")); //document.getElementsByTagName('*').length 201

这时,domlist就拥有了Array所有方法。

c. 简写 Array.prototype.slice.call(arguments)

有时候觉得 Array.prototype.slice.call(arguments) 这种写法太长了,怎么办呢?

var slice = Function.prototype.call.bind(Array.prototype.slice);
var a={0:'x',1:'y',2:'z',length:3};
var b=slice(a); //["x","y","z"]

d.如果想给指定函数绑定指定的上下文

var bind = Function.prototype.call.bind(Function.prototype.bind);
var context = { foo: "bar" };
function returnFoo () {
return this.foo;
}
var amazing = bind(returnFoo, context);

amazing(); // => bar


4.思考题:

var slice = Array.prototype.slice.call;

slice([1,2,3], 0, 1);

会出现什么结果?

答案见链接:

关于this

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值