简介
每个函数都包含两个非继承而来的方法:
apply()
和call()
;
call
与apply
都属于Function.prototype
的一个方法,所以每个function
实例都有call
、apply
属性;
作用
它们共同的作用:
call
和apply
和bind
都是用来修改函数中this
的指向问题;
区别
call()
:第一个参数是this
的指向,没有参数默认指向window
。在使用call()
方法时,传递给函数的参数必须逐个列举出来。(不会产生新的函数,只是在调用时,绑定一下而已)
apply()
:第一个参数是this
的指向,没有参数默认指向window
。在使用apply()
方法时,传递给函数的是参数数组。(就参数和call不一样其他都一样,不会产生新的函数,只是在调用时,绑定一下而已)
bind()
:第一个参数是this
的指向,没有参数默认指向window
。在使用call()
方法时,传递给函数的参数必须逐个列举出来。(语法和call一模一样,区别在于立即执行还是等待执行,bind会产生新的函数,bind不兼容IE6~8)
代码举例
var name = 'Evan';
var age = 20;
var person = {
name: 'Hillary',
age: 19,
sayIntroduce: function () {
return "Hello, My name is " + this.name + " and I'm " + this.age + ' years old.'
},
sayHobby: function (val1, val2) {
return "I'm " + this.name + ", I like " + val1 + " and " + val2 + ".";
}
}
var person1 = {
name: 'Coy'
}
console.log(person.sayIntroduce()); // Hello, My name is Hillary and I'm 19 years old.
当我们通过 call
和 apply
来改变this
的指向时,不传任何参数,则默认为将this
指向修改为 windows
// 当没有参数时,默认将this指向 window
console.log(person.sayIntroduce.call()); // Hello, My name is Evan and I'm 20 years old.
console.log(person.sayIntroduce.apply()); // Hello, My name is Evan and I'm 20 years old.
有参数时,this
指向第一个参数:
// 将this指向 person1,由于person1中没有age属性,因此为 undefined
console.log(person.sayIntroduce.call(person1)); // Hello, My name is Coy and I'm undefined years old.
console.log(person.sayIntroduce.apply(person1)); // Hello, My name is Coy and I'm undefined years old.
当需要传递参数时,call
可以直接写多个参数,apply
需要用数组方式传递:
console.log(person.sayHobby.call(person1, 'swimming', 'hiking')); // I'm Coy, I like swimming and hiking.
console.log(person.sayHobby.apply(person1, ['swimming', 'hiking'])); // I'm Coy, I like swimming and hiking.
bind()
不是立即执行
person.sayHobby.call(person1, 1, 2); // 改变sayHobby中的this,并且把sayHobby立即执行
person.sayHobby.bind(person1, 1, 2); // 改变sayHobby中的this,sayHobby并不执行
bind会把sayHobby中的this预处理为person1,此时sayHobby没有执行,当点击的时候才会把sayHobby执行
document.onclick = person.sayHobby.bind(person1);
下面是一个构造函数的例子:
//构造函数应用
function Grade(max, min, average) {
this.max = max;
this.min = min;
this.average = average;
}
function Subject(subjectName,max, min, average) {
Grade.call(this, max, min, average);
this.subjectName = subjectName;
}
var math = new Subject('math', 99, 60, 80);
console.log(math);