网站首页 > 技术文章 正文
apply和call都属于函数对象的方法,因此所有函数都可以用这两个方法。
apply方法用于解决这样一个问题:一个对象如何调用不属于它的方法?
例如:
var o = {
a:1,
b:2
}
function add(i, j){
console.log(i + j);
}
对象o如何调用add方法?最简单的思路是直接将add方法添加到对象o中。
o.plus = add;
这样就可以调用了
o.plus(o.a, o.b); // 3
这么做的问题是对象o被修改了,不好。那么如何在不修改对象o的前提下实现此目的呢?答案就是使用apply。
add.apply(o, [o.a, o.b]); // 3
apply的作用可以理解为:将某个方法应用到某个对象上。
所有方法(函数)的调用一定是作为某个对象的方法进行调用的,apply就是用于指定调用函数的对象。
apply接收两个实参,第一个就是指定的对象,或者是this。this表示apply执行时的作用域环境,如果是在全局环境下调用apply,那么this指全局对象,如果是在局部环境下(也就是某个函数里)调用,那么this指该局部环境(也就是某个函数的作用域)。如果传入的参数是null或undefined,会被自动转换为全局对象。
假设上述代码都在全局环境下,那么下列三种写法是一样的:
add.apply(o, [o.a,o.b]); // 3, 由对象o调用
add.apply(this, [o.a,o.b]); // 3, 在全局作用域下调用(或者说在Global/window对象上调用)
add.apply(null, [o.a,o.b]); // 3, 在全局作用域下调用(或者说在Global/window对象上调用)
但是!在ES5严格模式下,无论第一个参数传入的是什么,都会被统一的转换为this,即第一个参数只能是this。
第二个参数是调用函数时所传入的参数,必须是一个数组,或者直接传入arguments对象。可选填。
call方法的作用和apply是完全一样的,其区别仅在于call的参数写法不同,除第一个参数和apply是一样的,而其余参数需要逐一列举出来。
add.call(o, o.a, o.b); // 3
有了apply和call,我们可以将函数指派给任何对象,或者说任何对象都能够调用任何函数(道理上没错,至于能不能起作用,完全取决于实际代码)。
简单总结:
foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments) == this.foo(arg1, arg2, arg3)
来看一个实用案例:
求数组中的最大/最小值
var arr = [1, 2, 3]; // 数组对象本身没有求最大/最小值的方法,因此借用Math对象的方法
var maxNum = Math.max.apply(this,arr); // 只能用apply,不能用call
console.log(maxNum); // 3
apply和call还可以实现对象之间的继承。显然,对象应该由构造函数的形式创建,才能运用这两个方法。
这里借用了阮一峰老师的例子。
// 一个"动物"对象
function Animal{
this.species = "动物";
}
// 一个"猫"对象 function Cat(name, color){
this.name = name;
this.color = color;
}
// 在"猫"的构造函数中绑定"动物"
function Cat(name, color){
Animal.apply(this); // Animal中的this现在指向Cat
// 构造一个实例,看看"猫"是否继承了"动物"的属性
var cat = new Cat("大毛", "黄色");
alert(cat.species); // 动物,说明"猫"继承了"动物"的属性
这些简单例子仅能帮助理解apply和call的基本用法,要想熟练使用,发挥其真正的威力,还得多看高手源码、多实践。
- 上一篇: 延迟加载图像以提高Web网站性能的五种方法「实践」
- 下一篇: 牛客网错题
猜你喜欢
- 2024-11-21 浅析GIF 格式图片的存储与解析
- 2024-11-21 如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下
- 2024-11-21 快速了解ES6的代理与反射
- 2024-11-21 「实战」蘑菇街 PC 端首页,瀑布流布局的实现原理与细节技巧
- 2024-11-21 Knative 驾驭篇:带你 '纵横驰骋' Knative 自动扩缩容实现
- 2024-11-21 ECMAScript 6使用教程总结
- 2024-11-21 一道二进制子串算法,让面试官都解不出来?
- 2024-11-21 高级前端进阶,为什么要使用call、apply、bind?
- 2024-11-21 碎片时间学编程「202]:分组数组元素
- 2024-11-21 从入门到入土:Lambda完整学习指南,包教包会(上)
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-