一:this指向
this的指向,是当我们调用函数时确定的,调用方式的不同 决定了this指向的不同,一般是指向函数的调用者
调用方式 | this指向 |
---|---|
普通函数 调用 | window |
构造函数调用 | 实例对象 原型对象里面的方法也是指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
<body>
<button>点击</button>
<script>
//函数的不同调用方式决定了this 的指向不同
//1.普通函数 this指向window
function fn() {
console.log('普通函数的this' + this);
}
window.fn();
//fn.call();
//2.对象的方法 this指向函数调用者 也就是 对象o
var o = {
sayHi: function() {
console.log('对象方法的this' + this);
}
}
o.sayHi();
//3.构造函数 this指向 s 这个实例对象 原型对象里面的this 指向 的也是 s 这个实例对象
function Star() {};
Star.prototype.sing = function() {};
var s = new Star();
//4.绑定事件函数 this指向的是函数的调用者 btn这个对象
var btn = document.querySelector('button');
btn.onclick = function() {
console.log('绑定事件函数的this:' + this);
};
//5.定时器函数 this指向window
window.setInterval(function() {
console.log('定时器函数的this:' + this);
}, 1000); //定时器自动1s调用一次
// 6.立即执行函数(函数)() this指向window对象
(function() {
console.log('立即执行函数的this:' + this);
})();
//立即执行函数是自动调用的
</script>
</body>
二:改变this指向
1.call()方法
call()方法 可以调用一个对象,简单理解为调用函数的方式,但是可以改变函数this的指向
fun.call(thisArg,arg1,arg2,…)
- thisArg:在fun函数运行时指定this的值
- arg1,arg2:传递的其他参数
- 返回值就是函数的返回值,因为他就是调用函数
- 因此我们想改变this指向,同时想调用这个函数的时候,可以使用call,比如继承
<script>
//改变函数内this指向 js提供了三种方法 call() apply() bind()
//1.call()
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
}
// fn();
// fn.call();
fn.call(o, 1, 2);
//call() 第一:可以调用函数 第二:可以改变函数内的this指向
//call() 的主要作用 可以实现继承
function Father(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname, age, sex) {
Father.call(this, uname, age, sex);
}
var son = new Son('ldh', 18, '男');
console.log(son);
//2.apply()
//3.bind()
</script>
2.apply()方法
apply()方法调用一个函数,可以调用函数以及改变函数this指向
fun.apply(thisArg,[argsArray])
- thisArg:在fun函数运行时指定this的值
- argsArray:传递的值,必须包含在数组里
- 返回值就是函数的返回值,因为他就是调用函数
- 因此apply()主要跟数组有关系,比如使用Math.max()求数组最大值
<script>
//改变函数内this指向 js提供了三种方法 call() apply() bind()
//2. apply() 应用 运用的意思
var o = {
name: 'andy'
}
function fn(arr) {
console.log(this);
console.log(arr); //打印的结果是字符串 不是数组 在这里注意:传入的数组里面是数字类型的得到的就是数字 传入的是字符串类型的 拿到的就是字符串
}
fn.apply(o, ['pink']); //此时 fn里的this就指向了o这个对象
//1. 作用: 第一:调用函数 第二: 改变函数内部this指向
//2. 但是参数必须是数组形式[]传递的 或者伪数组
//3.apply 的主要应用
//例如可以利用 apply借助于数学内置对象 求最大值
// Math.max()
var arr = [1, 44, 51, 95, 78];
//var max = Math.max.apply(null, arr); //调用Math.max()函数 null:不改变this指向 arr:数组 把arr传递给Math.max()方法
var max = Math.max.apply(Math, arr); //写成null不太好 所以我们把他写成函数的调用者 Math
var min = Math.min.apply(Math, arr); //写成null不太好 所以我们把他写成函数的调用者 Math
console.log(max, min); //95 1
var max1 = Math.max(1, 2, 3);
console.log(max1); //3
</script>
3.bind()方法
bind()方法 不调用函数,但是能改变函数内部的this指向
fun.bind(thisArg,arg1,arg2,…)
- thisArg:在fun函数运行时指定this的值
- arg1,arg2:传递的其他参数
- 返回值就是函数的返回值,因为他就是调用函数
- 因此我们想改变this指向,但是并不像调用这个函数时,就可以使用bind()
<body>
<button>点击</button>
<script>
//改变函数内this指向 js提供了三种方法 call() apply() bind()
//3. bind() 绑定 捆绑的意思
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
}
//注意 bind()并不会调用函数 只是绑定 不执行!!!!! 只是改变this的指向
//返回由指定的this值和初始化参数改造的 原函数 拷贝
//定义一个 f 接收返回的新函数
var f = fn.bind(o, 1, 2); //让fn绑定了o 也就是让this指向o
f();
//1.不会调用原来的函数 可以改变原来的函数内部this的指向
//2.返回的是原函数改变this之后产生的的新函数
//3.如果有的函数我们不需要立即调用但是又想改变这个函数内部的this指向 此时用bind
//4.我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒之后开启这个按钮
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
this.disabled = true; //this指向函数调用者btn
// var that = this; //把 btn 保存起来给that 缺点:重新开辟内存空间
var timer = setTimeout(function() {
// this.disabled = false; //定时器函数里面的this指向的是window
//btn.disabled = false; //如果这样写的话缺点:如果var btn1 还要在这里也改成btn1 很麻烦 如果有多个按钮就不知道是谁了
// that.disabled = false;
//思路 让定时器里面的this指向btn 但是不是立即调用
this.disabled = false;
//让bind 绑定定时器的函数 注意是在函数外面绑定的 并且让定时器函数的this指向btn
}.bind(this), 3000) //这个bind(this)中的this指向的是btn
})
</script>
</body>
三:call apply bind 总结
相同点:
都可以改变函数内部的this指向
不同点:
- call 和 apply 会调用函数,并且改变函数内部的this 指向.
- bind 不会调用函数,可以改变函数内部this指向
- call 和 apply 传递的参数不同,call传递的参数是arg1,arg2…形式 但是apply传递的参数必须是数组[arg]形式的
主要运用场景
- call经常做继承
- apply经常跟数组有关系,比如借助数学对象实现数组最大值和最小值
- bind不调用函数,但是还想改变this指向.比如改变定时器内部的this指向。