在ES3给Function的原因定义了两个方法,Function.prototype.call和Function.prototype.apply。
call与apply的区别
call与apply具有相同的作用,二者的区别主要再传入的参数不同。
apply接受两个参数,第一个参数指定函数体内this对象的指向,第二个参数为一个带下标的集合,这个集合是一个数组或者类数组,apply方法把这个集合中的元素传递给被调用的函数。
let func = function(a,b,c) {
console.log(a)
console.log(b)
console.log(c)
}
func.apply(null,[1,2,3]) // 1,2,3
call传入的参数数量不是固定的,第一个参数也代表函数体内的this指向,第二个参数开始往后,每个参数被依次传入函数
let func = function(a,b,c) {
console.log(a)
console.log(b)
console.log(c)
}
func.call(null,4,3,2]) // 4,3,2
在使用call和apply的时候,如果我们传入的第一个参数是null,函数体内的this会指向默认的宿主对象,在浏览器中则是window
call与apply的用途
-
改变this指向
改变this指向是最常见的用途。直接上例子
let obj1 = {
name: 'lta'
}
let obj2 = {
name: 'xtt'
}
window.name = 'window'
let getName = function() {
console.log(this.name)
}
getName.call(null) // window
getName.call(obj1) // lta
getName.call(obj2) // xtt
- 借用其他对象的方法或属性
let person = function() {
this.name = 'lta'
}
let person1 = function() {
this.getName = function() {
console.log(this.name)
}
person.call(this)
}
let _person1 = new person1()
_person1.getName() // lta
-
调用其他函数
apply和call方法都可以用来直接调用函数
let person = function(name) {
console.log(name)
}
person.call(null, 'lta') // lta
call与bind的区别
- bind返回的是一个函数
let person = {
name: 'lta'
}
let func = function() {
console.log(this.name)
}
let func1 = func.bind(person)
func1() // lta
bind返回的方法不会被立刻执行,而是返回一个改变了上下文this后的函数,而员函数func中的this并没有被改变,依旧指向window。
-参数的使用
function func(a, b, c) {
console.log(a, b, c);
}
var func1 = func.bind(null,'lta');
func('A', 'B', 'C') // A B C
func1('A', 'B', 'C') // lta A B
func1('B', 'C') // lta B C
func.call(null, 'lta') // lta undefined undefined