1. 什么是this
- this是Javascript语言的一个关键字
- 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
- 随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象
1) 全局范围内使用this
在全局范围内使用this ,它将指向全局对象(浏览器中为 window)
var name = 'name'
console.log(name); //name
console.log(this.name); //name
console.log(window.name); //name
console.log(this); //Window对象
2) 函数中this指向函数的调用者也就是window(window.test)
function test(){
this.x = 1;
alert(this.x);
console.log(this);//window
}
test(); // 1
3) 在事件中this指向的触发事件的元素
<body>
<button onclick = "fun(this)">点击</button>
<script>
function fun(_this){
console.log(_this); // 当前元素 <button onclick="fun(this)"> 点击 </button>
}
</script>
</body>
4) 对象中的this指的就是对象本身
let obj = {
name:'jack',
say:function(){
console.log(this);//Object
}
}
obj.say()
6) 定时器中的this指向window
7) 箭头函数中的this:谁定义了箭头函数,this就是谁
箭头函数中的this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在this!
1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中this 的值和外层的this 是一样的
2.箭头函数中的this引用的就是最近作用域中的this
3.向外层作用域中,一层一层查找this,直到有this的定义
let user = {
name:'小明',
walk: ()=>{
console.log(this);//指向window,和函数声明环境中this一致
}
}
user.walk();
2. call(),apply(),bind() 方法
call和apply 中的this指的是当前元素本身,传递进去之后,会修改方法里面的this指向,所有函数都是对象,都有call(),apply(),bind()方法,都是为了改变this指向
1) call方法
语法格式:fun.call(this,obj1,obj2);
let box1 = document.querySelector('.box1') function fun(){ console.log(this); //fun不加call之前指向window } box1.onclick = function(){ fun.call(this); // 使用call,修改this指向,指向调用事件的元素 }
2) apply方法
call和apply相似,不同指出在于传递的方式不同,call的参数需要逐个列举,apply的参数需要通过数组的形式传递
语法格式:fun.apply(this,[obj1,obj2]);
let box1 = document.querySelector('.box1') function fun(){ console.log(this); //触发事件元素本身 } function fun2(a,b){ console.log(a+b); console.log(this); //触发事件元素本身 } box1.onclick = function(){ console.log(this); //触发事件元素本身 fun.apply(this) //改变this指向 fun2.apply(this,[10,20]) //改变this指向 }
3) bind方法
bind有两个特点
- 不会调用函数
- 可以改变函数内部this指向
bind()方法不会调用函数,但是能改变函数内部this指向
语法格式:Fun.bind(this,arg1,arg2);
let Obj = { name:'jack', age:18 } function fun() { console.log(this); } // 把fun中的this指向,指向到Obj身上 // let newFun = fun.bind(Obj); // newFun(); // 这时候fun中的this,就变成了obj (fun.bind(Obj))() //自执行函数直接调用
三者的区别
- call 和 apply 特性一样
都是用来调用函数,而且是立即调用
call 调用的时候,参数必须以参数列表的形式进行传递,也就是以逗号分隔的方式依次传递即可
apply 调用的时候,参数必须是一个数组,然后在执行的时候,会将数组内部的元素一个一个拿出来,与形参一一对应进行传递
bind
可以用来指定内部 this 的指向,以参数列表的形式进行传递,和call一样用逗号分隔的方式依次传递然后生成一个改变了 this 指向的新的函数