一、call()
// 1、call()
var obj = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
}
fn.call(obj, 1, 2); // 此时的this指向 obj
// call()可以调用函数,也可以改变函数内this的指向
// call的主要作用可以实现继承,
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
function Son(uname, age) {
// 调用father函数,并且把父构造函数里的this指向了子构造函数
Father.call(this, uname, age);
}
var son = new Son('刘德华', 33);
console.log(son);
</script>
二、bind()
var obj = {
name: 'andy'
}
function fn(x, y) {
console.log(this);
console.log(x + y);
}
var f = fn.bind(obj, 1, 2); //返回的是一个函数,所以此时的f是一个函数
f();
// 1、不会调用原来的函数,可以改变雨来函数内部this的指向
// 2、返回的是原函数改变 this 之后产生的新函数
// 3、如果有的函数我们不需要立即调用,但是又想改变这个函数内部的 this 指向,此时用 bind最合适
// 4、例如:我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
var btn = document.querySelector('button');
btn.onclick = function() {
this.disabled = true; // 这个this指向的是btn
// 相当于给定时器绑定了一个bind()方法,他不会立即调用这个函数
setTimeout(function() {
this.disabled = false; // 这个this指向的是window
}.bind(this), 3000); // 这个this指向的是 btn这个对象,也就实现了改变定时器里 this的指向
}
三、apply()
var obj = {
name: 'andy'
}
function fn(arr) {
console.log(this);
console.log(arr); // red (打印出来的是字符串形式)
}
fn.apply(obj, ['red']);
// (1)、可以调用函数,也可以改变函数内this的指向
// (2)、但是它的参数必须是数组(伪数组)
// (3)、apply() 的主要应用:比如说我们可以利用apply() 借助于数学内置对象来求最大值
var arr = [2, 5, 45, 23];
var max = Math.max.apply(Math, arr);
var min = Math.min.apply(Math, arr);
console.log(max, min); // 45,2
四、相同点:
都可以改变函数内 this 的指向
五、区别
传递参数方式 | 是否直接调用函数 | 主要应用场景 | |
call() | call(obj,aru1,aru2...) | 是 | 做继承 |
bind() | bind(obj,aru1,aru2...) | 否 | 不调用函数,并且想要改变函数内部的this指向 |
apply() | apply(obj,[ ] )传递的参数是一个数组 | 是 | 跟数组有关系的 |