JS中this
1.普通函数中
function(){
console.log(this)
}
//this指向的是window
2.对象的方法中
var a = {
fn:function{
console.log(this)
}
}
//是这个对象a
3.构造函数中
function Star(){
console.log(this)
}
是new 出来的那个对象实例,因为new才会调用构造函数
原型对象中的this,也是new出来的实例对象
4.绑定事件函数中
bth.onclick = function(){
console.log(this)
}
this指向的是触发这个函数的控件
5.定时器函数中
setInterval(function(){
},1000);
其实应该这么写
window.setInterval(function(){
},1000);
所以指向的是window对象
6.立即指向函数中
(function(){
console.log(this)
})()
指向的也是window
7.控制this指向的方法
在改变this时首先确定原函数中使用了this
被指向的对象不写是,用null替代,或原对象,
原函数.call(被指向的对象)
call和apply会立即调用函数,bind不会,需手动调用
1.call()
call()可以调用函数
也能改变函数中this的指向
实现继承
var o = {
}
function fn(){
}
fn.call()//调用函数
fn.call(o,1,2,3,4)//改变this
function Father(a,b){
this.a = a
this.b= b
}
function Son(a,b){
Father.call(this,a,b)//相当于写了父类里面的赋值
}
var son = new Son(1,2)
console.log(son)//{a:1,b:2}
//其实就是在new Son时,调用了父类的构造函数,父类调用时的实参是Son的形参,之后调用父类的构造函数.
//把形参赋值给了父类构造函数的实例的a和b,但是由于call的存在, 改变了this指向,此时的父类构造函数中的this指向的是Son的实例.此时就能看到Son实例的属性时根据父类写的操作来执行的.
2.bind()
bind方法不会调用函数,需要手动调用
参数不能传递数组
返回由指定的this值和初始化参数改造的原函数拷贝
相当于返回了一个新函数
一般bind是和事件和定时器连用,事件中一般this指向的都是调用者,在不能使用this的情况下,可以使用bind
var a = {
}
function fn(a,b,c){
this.a = a
this.b = b
this.c= c
}
var fn2 = fn.bind(a)
fn2()
此时fn2中的this指向了a
bth.onclick = function(){
this.disabled = true;
setTimeout(function(){
this.disabled = false
}.bind(this),3000)
}
//这是一个点击事件,在点击后按钮禁用,在过了3秒后才会把按钮解开,而定时器中的this指向的使window,所以用bind,在3秒后把this指向bth,解禁按钮,而apply和call会立即调用this.disabled,所以不能用.
var bths = document.querySelectorAll("button");
for(var i = 0;i<bths.length;i++){
bth[i].onclick = function(){
this.disabled = true;
setTimeout(function(){
this.disabled = false
}.bind(this),2000)
}
}
//这样定时器中的this就指向了点击的按钮.其实就是保存了那个i,用let和保存i也能实现,不用bind.
3.apply()
经常和数组使用
传入的参数必须是一个数组或者伪数组
主要用来使数组使用数学内置对象中的方法.
var a = {
}
function fn(arr){
this.name = arr
}r
fn.apply(a,[1])//{name :1}
var b = [1,23,5]
Math.max.apply(null,b)//23
null可以写成Math,因为不需要改变this
这就相当于调用了数学的max方法.