JS中的call()和apply()

一、call()和apply()的语法、参数

1.call()方法调用一个函数,其具有一个指定的this值和分别地提供的参数(参数的列表)。

语法:fun.call(this.Arg, arg1, arg2, …)

参数
thisArg:在fun函数运行时指定的this值。需要注意的是,指定的this值不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
arg1, arg2, …:指定的参数列表。

返回值:返回结果包括指定的this值和参数。

描述:可以让call()中的对象调用当前对象所拥有function。可以使用call()来实现继承:写一个方法,然后让另外一个新的对象来继承它(多个对象都有相同属性不用重复写)。

代码实例

 // 使用call方法调用父构造函数
 function Product(name, price) {
     this.name = name;
     this.price = price;

     if (price < 0) {
         throw RangeError('Cannot create product' + this.name + ' with a negative price');
     }
 }

  function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
  }

// 等同于
//    function Food(name, price) {
//        this.name = name;
//        this.price = price;
//        if (price < 0) {
//            throw RangeError('Cannot create product' + this.name + ' with a negative price');
//        }
//
//        this.category = 'food';
//    }

// function Toy 同上
function Toy(name, price) {
    Product.call(this, name, price);
    this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
console.log(cheese.category);    // food
console.log(fun.category);     // toy

2.apply()与call()方法相似,不同点在于提供参数的方式。apply使用参数数组而不是一组参数列表。
他的语法是:fun.apply(thisArg, [argsArray])

argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给fun函数。如果该参数的值为null或undefined,则表示不需要传入任何参数。
也可以使用 arguments 对象作为argsArray参数。arguments是一个函数的局部变量。它可以被用作被调用对象的所有未指定的参数。这样,在使用apply函数的时候就不需要知道被调用对象的所有参数。

代码实例

// 定义一个学生类
 function Person(name, age) {
     this.name = name;
     this.age = age;
 }
 // 定义一个学生类
 function Student(name, age, grade) {
     Person.apply(this, arguments);
     this.grade = grade;
 }
 var student = new Student("Jasper" , 4 , "小班");
 console.log("name: " + student.name + ", age: " + student.age + ", grade: " + student.grade);
 // name: Jasper, age: 4, grade: 小班

二、在什么情况下分别使用call()和apply()

  1. 在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));

  2. 在参数较多且按顺序传递的时候,使用apply()方便一些,不需要把参数一个一个写上。

三、apply的巧妙用处

apply()可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) 。

1.Math.max 可以实现得到数组中最大的一项

Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组 ,但是它支持Math.max(param1,param2,param3…),所以可以根据apply的这个特点来解决:

var max=Math.max.apply(null,array);

这样轻易的可以得到一个数组中最大的一项 。(这块在调用的时候第一个参数给了一个null,是因为没有对象去调用这个方法,只需要用这个方法来进行运算,得到返回的结果就可以,所以直接传递了一个null)

2.Math.min 可以实现得到数组中最小的一项

var min=Math.min.apply(null,array);

3.Array.prototype.push 可以实现两个数组合并

同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN),所以同样也可以通过apply来装换一下这个数组,即:

var arr1 = new Array("1","2","3");   
var arr2 = new Array("4","5","6");   
Array.prototype.push.apply(arr1,arr2);   

也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.

通常在什么情况下,可以使用apply类似Math.min等之类的特殊用法:
一般在目标函数只需要n个参数列表,而不接收一个数组的形式,可以通过apply的方式巧妙地解决问题!


参考文档:
MDN call()方法

MDN apply()方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值