面向对象 - apply
apply
方法的作用与 call 方法类似,也是改变 this 指向,然后再调用该函数。唯一的区别就是,它接受一个数组作为函数执行时的参数,使用格式如下
func.apply(thisValue, [arg1, arg2, ...])
apply
方法的第一个参数也是 this
所要指向的那个对象,如果设为 null
或 undefined
,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员一次作为参数,传入原函数。原函数的参数,在 call
方法中必须一个个添加,但是在 apply
方法中,必须以数组形式添加
function f(x, y) {
console.log(x + y)
}
f.call(null, 1, 1) // 2
f.apply(null, 1, 1) // 2
上面代码中,f 函数本来接受两个参数,使用 apply 方法以后,就变成可以接受一个数组作为参数
这一点利用,可以做一些有趣的应用
找出数组最大元素
Javascript
不提供找出数组最大元素的函数。结合使用 apply
方法和 Math.max
方法,就可以返回数组的最大元素
var a = [10, 2, 4, 15, 9]
Math.max.apply(null, a) // 15
将数组的空元素变为 undefined
undefined
通过 apply
方法,利用 Array
构造函数将数组的空元素变成 undefined
Array.apply(null, ['a', ,'b'])
// ['a', undefined, 'b']
空元素与undefined
的差别在于,数组的 forEach
方法会跳过空元素,但是不会跳过 undefined
。因此,遍历内部元素的时候,会得到不同的结果
var a = ['a', , 'b']
function print(i) {
console.log(i)
}
a.forEach(print)
// a
// b
Array.apply(null, a).forEach(print)
// a
// undefined
// b
转换类似数组的对象
另外,利用数组对象的 slice
方法,可以将一个类似数组的对象(比如 arguments
对象)转为真正的数组
Array.prototype.slice.apply({0: 1, length: 1}) // [1]
Array.prototype.slice.apply({0: 1}) // []
Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
Array.prototype.slice.apply({length: 1}) // [undefined]
上面代码的 apply
方法的参数都是对象,但是返回结果都是数组,这就起到了将对象转成数组的目的。从上面代码可以看到,这个方法起作用的前提是,被处理的对象必须有 length
属性,以及相对应的数字键
绑定回调函数的对象
前面的按钮点击时间的例子,可以改写如下
var o = new Object()
o.f = function () {
console.log(this === o)
}
var f = function () {
o.f.apply(o)
// 或者 o.f.call(o)
}
$('#button').on('click', f)
上面代码中,点击按钮以后,控制台将会显示 true。由于 apply 方法(或者 call 方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。
Last updated
Was this helpful?